Evaluar y enviar comentarios
Contraer todo/Expandir todo Contraer todo
Esta página es específica de
Microsoft Visual Studio 2008/.NET Framework 3.5

Hay además otras versiones disponibles para:
Biblioteca de clases de .NET Framework
DataGridViewComboBoxColumn (Clase)

Actualización: noviembre 2007

Representa una columna de objetos DataGridViewComboBoxCell.

Espacio de nombres:  System.Windows.Forms
Ensamblado:  System.Windows.Forms (en System.Windows.Forms.dll)
Visual Basic (Declaración)
<ToolboxBitmapAttribute(GetType(DataGridViewComboBoxColumn), "DataGridViewComboBoxColumn.bmp")> _
Public Class DataGridViewComboBoxColumn _
    Inherits DataGridViewColumn
Visual Basic (Uso)
Dim instance As DataGridViewComboBoxColumn
C#
[ToolboxBitmapAttribute(typeof(DataGridViewComboBoxColumn), "DataGridViewComboBoxColumn.bmp")]
public class DataGridViewComboBoxColumn : DataGridViewColumn
Visual C++
[ToolboxBitmapAttribute(typeof(DataGridViewComboBoxColumn), L"DataGridViewComboBoxColumn.bmp")]
public ref class DataGridViewComboBoxColumn : public DataGridViewColumn
J#
/** @attribute ToolboxBitmapAttribute(DataGridViewComboBoxColumn, "DataGridViewComboBoxColumn.bmp") */
public class DataGridViewComboBoxColumn extends DataGridViewColumn
JScript
public class DataGridViewComboBoxColumn extends DataGridViewColumn

La clase DataGridViewComboBoxColumn es un tipo especializado de DataGridViewColumn que se utiliza para alojar de manera lógica celdas que permiten a los usuarios seleccionar valores en una lista de opciones. Un elemento DataGridViewComboBoxColumn tiene un elemento DataGridViewComboBoxCell asociado en cada objeto DataGridViewRow que interseca con él.

Puede rellenar las celdas manualmente estableciendo sus propiedades Value. Como alternativa, puede enlazar la columna al origen de datos indicado por la propiedad DataGridView..::.DataSource. Si la DataGridView está enlazada a una tabla de base de datos, establezca la propiedad DataPropertyName de la columna en el nombre de una columna de la tabla. Si la DataGridView está enlazada a una colección de objetos, establezca la propiedad DataPropertyName en el nombre de una propiedad de objeto.

Puede rellenar manualmente la lista desplegable de columnas agregando valores a la colección de Items. Como alternativa, puede enlazar la lista desplegable a su propio origen de datos estableciendo la propiedad DataSource de columna. Si los valores son objetos de una colección o registros de una tabla de base de datos, también se deben establecer las propiedades DisplayMember y ValueMember. La propiedad DisplayMember indica qué propiedad de objeto o columna de base de datos proporciona los valores que se muestran en la lista desplegable. La propiedad ValueMember indica qué propiedad de objeto o columna de base de datos se utiliza para establecer la propiedad Value de celda.

Una situación típica es enlazar el control DataGridView a una tabla de base de datos primaria y enlazar la lista desplegable a una tabla secundaria relacionada. Por ejemplo, se puede enlazar el control DataGridView a una tabla Orders que contiene una columna ProductID y establecer la propiedad DataSource de columna en una tabla Products que contiene las columnas ProductID y ProductName. En este caso, se establecería la propiedad DataPropertyName de columna en "ProductID" para rellenar los valores de sus celdas a partir de la columna Orders.ProductID. Sin embargo, para mostrar los nombres reales de los productos en las celdas y en la lista desplegable, se han de asignar estos valores a la tabla Products estableciendo la propiedad ValueMember en "ProductID" y la propiedad DisplayMember en "ProductName".

Los valores de lista desplegable (o los valores indicados por la propiedad ValueMember) deben incluir los valores de celda reales pues, de lo contrario, el control DataGridView producirá una excepción.

Cuando se establecen las propiedades DataSource, DisplayMember y ValueMember de columna, se establecen automáticamente las propiedades correspondientes de todas las celdas de la columna, incluida la propiedad CellTemplate. Para reemplazar los valores de estas propiedades para celdas específicas, establezca primero la propiedad de columna y, a continuación, establezca las propiedades de celda.

A diferencia del control ComboBox, DataGridViewComboBoxCell no tiene las propiedades SelectedIndex ni SelectedValue. En su lugar, cuando se selecciona un valor de una lista desplegable, se establece la propiedad Value de celda.

El modo de ordenación predeterminado de este tipo de columnas es NotSortable.

Notas para los herederos:

Cuando derive del control DataGridViewComboBoxColumn y agregue nuevas propiedades a la clase derivada, asegúrese de reemplazar el método Clone para copiar las nuevas propiedades durante las operaciones de clonación. También debe llamar al método Clone de la clase base para que las propiedades de esta clase se copien en la nueva celda.

En el ejemplo de código siguiente se muestra cómo se utiliza DataGridViewComboBoxColumn para facilitar la entrada de datos en la columna TitleOfCourtesy.

Visual Basic
Imports System
Imports System.Data
Imports System.Data.SqlClient
Imports System.Windows.Forms
Imports System.Collections.Generic
Imports System.Drawing

Public Class Employees
    Inherits System.Windows.Forms.Form

    Private WithEvents DataGridView1 As New DataGridView
    Private WithEvents DataGridView2 As New DataGridView

    <STAThreadAttribute()> _
    Public Shared Sub Main()
        Try
            Application.EnableVisualStyles()
            Application.Run(New Employees())
        Catch e As Exception
            MessageBox.Show(e.Message & e.StackTrace)
        End Try
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles MyBase.Load

        Try
            SetUpForm()
            SetUpDataGridView1()
            SetUpDataGridView2()
        Catch ex As SqlException
            MessageBox.Show("The connection string <" _
                & connectionString _
                & "> failed to connect.  Modify it to connect to " _
                & "a Northwind database accessible to your system.", _
                "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            Application.Exit()
        End Try
    End Sub

    Private Sub SetUpForm()
        Size = New Size(800, 600)
        Dim flowLayout As New FlowLayoutPanel()
        flowLayout.FlowDirection = FlowDirection.TopDown
        flowLayout.Dock = DockStyle.Fill
        Controls.Add(flowLayout)
        Text = "DataGridView columns demo"

        flowLayout.Controls.Add(DataGridView1)
        flowLayout.Controls.Add(DataGridView2)
    End Sub

    Private Sub SetUpDataGridView2()
        DataGridView2.Dock = DockStyle.Bottom
        DataGridView2.TopLeftHeaderCell.Value = "Sales Details"
        DataGridView2.RowHeadersWidthSizeMode = _
        DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders
    End Sub

    Private Sub SetUpDataGridView1()
        ' Virtual mode is turned on so that the
        ' unbound DataGridViewCheckBoxColumn will
        ' keep its state when the bound columns are
        ' sorted.
        DataGridView1.VirtualMode = True

        DataGridView1.AutoSize = True
        DataGridView1.DataSource = _
            Populate("SELECT * FROM Employees")
        DataGridView1.TopLeftHeaderCell.Value = "Employees"
        DataGridView1.RowHeadersWidthSizeMode = _
            DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders
        DataGridView1.ColumnHeadersHeightSizeMode = _
            DataGridViewColumnHeadersHeightSizeMode.AutoSize
        DataGridView1.AutoSizeColumnsMode = _
            DataGridViewAutoSizeColumnsMode.AllCells
        DataGridView1.AllowUserToAddRows = False
        DataGridView1.AllowUserToDeleteRows = False

        ' The below autogenerated column is removed so 
        ' a DataGridViewComboboxColumn could be used instead.
        DataGridView1.Columns.Remove( _
            ColumnName.TitleOfCourtesy.ToString())
        DataGridView1.Columns.Remove(ColumnName.ReportsTo.ToString())

        AddLinkColumn()
        AddComboBoxColumns()
        AddButtonColumn()
        AddOutOfOfficeColumn()
    End Sub

    ' Using an enum provides some abstraction between column index
    ' and column name along with compile time checking, and gives
    ' a handy place to store the column names.
    Enum ColumnName
        EmployeeId
        LastName
        FirstName
        Title
        TitleOfCourtesy
        BirthDate
        HireDate
        Address
        City
        Region
        PostalCode
        Country
        HomePhone
        Extension
        Photo
        Notes
        ReportsTo
        PhotoPath
        OutOfOffice
    End Enum

    Private Sub AddComboBoxColumns()
        Dim comboboxColumn As DataGridViewComboBoxColumn
        comboboxColumn = CreateComboBoxColumn()
        SetAlternateChoicesUsingDataSource(comboboxColumn)
        comboboxColumn.HeaderText = _
            "TitleOfCourtesy (via DataSource property)"
        DataGridView1.Columns.Insert(0, comboboxColumn)

        comboboxColumn = CreateComboBoxColumn()
        SetAlternateChoicesUsingItems(comboboxColumn)
        comboboxColumn.HeaderText = _
            "TitleOfCourtesy (via Items property)"
        ' Tack this example column onto the end.
        DataGridView1.Columns.Add(comboboxColumn)
    End Sub

    Private Sub AddLinkColumn()

        Dim links As New DataGridViewLinkColumn()
        With links
            .HeaderText = ColumnName.ReportsTo.ToString()
            .DataPropertyName = ColumnName.ReportsTo.ToString()
            .ActiveLinkColor = Color.White
            .LinkBehavior = LinkBehavior.SystemDefault
            .LinkColor = Color.Blue
            .TrackVisitedState = True
            .VisitedLinkColor = Color.YellowGreen
        End With
        DataGridView1.Columns.Add(links)
    End Sub

    Private Shared Sub SetAlternateChoicesUsingItems( _
        ByVal comboboxColumn As DataGridViewComboBoxColumn)

        comboboxColumn.Items.AddRange("Mr.", "Ms.", "Mrs.", "Dr.")

    End Sub

    Private Function CreateComboBoxColumn() _
        As DataGridViewComboBoxColumn
        Dim column As New DataGridViewComboBoxColumn()

        With column
            .DataPropertyName = ColumnName.TitleOfCourtesy.ToString()
            .HeaderText = ColumnName.TitleOfCourtesy.ToString()
            .DropDownWidth = 160
            .Width = 90
            .MaxDropDownItems = 3
            .FlatStyle = FlatStyle.Flat
        End With
        Return column
    End Function

    Private Sub SetAlternateChoicesUsingDataSource( _
        ByVal comboboxColumn As DataGridViewComboBoxColumn)
        With comboboxColumn
            .DataSource = RetrieveAlternativeTitles()
            .ValueMember = ColumnName.TitleOfCourtesy.ToString()
            .DisplayMember = .ValueMember
        End With
    End Sub

    Private Function RetrieveAlternativeTitles() As DataTable
        Return Populate( _
            "SELECT distinct TitleOfCourtesy FROM Employees")
    End Function

    Private connectionString As String = _
            "Integrated Security=SSPI;Persist Security Info=False;" _
            & "Initial Catalog=Northwind;Data Source=localhost"

    Private Function Populate(ByVal sqlCommand As String) As DataTable
        Dim northwindConnection As New SqlConnection(connectionString)
        northwindConnection.Open()

        Dim command As New SqlCommand(sqlCommand, _
            northwindConnection)
        Dim adapter As New SqlDataAdapter()
        adapter.SelectCommand = command
        Dim table As New DataTable()
        table.Locale = System.Globalization.CultureInfo.InvariantCulture
        adapter.Fill(table)

        Return table
    End Function

    Private Sub AddButtonColumn()
        Dim buttons As New DataGridViewButtonColumn()
        With buttons
            .HeaderText = "Sales"
            .Text = "Sales"
            .UseColumnTextForButtonValue = True
            .AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells
            .FlatStyle = FlatStyle.Standard
            .CellTemplate.Style.BackColor = Color.Honeydew
            .DisplayIndex = 0
        End With

        DataGridView1.Columns.Add(buttons)

    End Sub

    Private Sub AddOutOfOfficeColumn()
        Dim column As New DataGridViewCheckBoxColumn()
        With column
            .HeaderText = ColumnName.OutOfOffice.ToString()
            .Name = ColumnName.OutOfOffice.ToString()
            .AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells
            .FlatStyle = FlatStyle.Standard
            .CellTemplate = New DataGridViewCheckBoxCell()
            .CellTemplate.Style.BackColor = Color.Beige
        End With

        DataGridView1.Columns.Insert(0, column)
    End Sub

    Private Sub PopulateSales( _
        ByVal buttonClick As DataGridViewCellEventArgs)

        Dim employeeId As String = _
            DataGridView1.Rows(buttonClick.RowIndex). _
            Cells(ColumnName.EmployeeId.ToString()).Value().ToString()
        DataGridView2.DataSource = Populate( _
            "SELECT * FROM Orders WHERE EmployeeId = " & employeeId)
    End Sub

#Region "SQL Error handling"
    Private Sub DataGridView1_DataError(ByVal sender As Object, _
    ByVal e As DataGridViewDataErrorEventArgs) _
    Handles DataGridView1.DataError

        MessageBox.Show("Error happened " _
            & e.Context.ToString())

        If (e.Context = DataGridViewDataErrorContexts.Commit) _
            Then
            MessageBox.Show("Commit error")
        End If
        If (e.Context = DataGridViewDataErrorContexts _
            .CurrentCellChange) Then
            MessageBox.Show("Cell change")
        End If
        If (e.Context = DataGridViewDataErrorContexts.Parsing) _
            Then
            MessageBox.Show("parsing error")
        End If
        If (e.Context = _
            DataGridViewDataErrorContexts.LeaveControl) Then
            MessageBox.Show("leave control error")
        End If

        If (TypeOf (e.Exception) Is ConstraintException) Then
            Dim view As DataGridView = CType(sender, DataGridView)
            view.Rows(e.RowIndex).ErrorText = "an error"
            view.Rows(e.RowIndex).Cells(e.ColumnIndex) _
                .ErrorText = "an error"

            e.ThrowException = False
        End If
    End Sub
#End Region

    Private Sub DataGridView1_CellContentClick(ByVal sender As Object, _
        ByVal e As DataGridViewCellEventArgs) _
        Handles DataGridView1.CellContentClick

        If IsANonHeaderLinkCell(e) Then
            MoveToLinked(e)
        ElseIf IsANonHeaderButtonCell(e) Then
            PopulateSales(e)
        End If
    End Sub

    Private Sub MoveToLinked(ByVal e As DataGridViewCellEventArgs)
        Dim employeeId As String
        Dim value As Object = DataGridView1.Rows(e.RowIndex). _
            Cells(e.ColumnIndex).Value
        If value.GetType Is GetType(DBNull) Then Return

        employeeId = CType(value, String)
        Dim boss As DataGridViewCell = _
            RetrieveSuperiorsLastNameCell(employeeId)
        If boss IsNot Nothing Then
            DataGridView1.CurrentCell = boss
        End If
    End Sub

    Private Function IsANonHeaderLinkCell(ByVal cellEvent As _
        DataGridViewCellEventArgs) As Boolean

        If TypeOf DataGridView1.Columns(cellEvent.ColumnIndex) _
            Is DataGridViewLinkColumn _
            AndAlso Not cellEvent.RowIndex = -1 Then _
            Return True Else Return False

    End Function

    Private Function IsANonHeaderButtonCell(ByVal cellEvent As _
        DataGridViewCellEventArgs) As Boolean

        If TypeOf DataGridView1.Columns(cellEvent.ColumnIndex) _
            Is DataGridViewButtonColumn _
            AndAlso Not cellEvent.RowIndex = -1 Then _
            Return True Else Return (False)

    End Function

    Private Function RetrieveSuperiorsLastNameCell( _
        ByVal employeeId As String) As DataGridViewCell

        For Each row As DataGridViewRow In DataGridView1.Rows
            If row.IsNewRow Then Return Nothing
            If row.Cells(ColumnName.EmployeeId.ToString()). _
                Value.ToString().Equals(employeeId) Then
                Return row.Cells(ColumnName.LastName.ToString())
            End If
        Next
        Return Nothing
    End Function

#Region "checkbox state"
    Dim inOffice As New Dictionary(Of String, Boolean)
    Private Sub DataGridView1_CellValuePushed(ByVal sender As Object, _
     ByVal e As DataGridViewCellValueEventArgs) _
        Handles DataGridView1.CellValuePushed

        If IsCheckBoxColumn(e.ColumnIndex) Then
            Dim employeeId As String = GetKey(e)
            If Not inOffice.ContainsKey(employeeId) Then
                inOffice.Add(employeeId, CType(e.Value, Boolean))
            Else
                inOffice.Item(employeeId) = CType(e.Value, Boolean)
            End If
        End If
    End Sub

    Private Function GetKey(ByVal cell As DataGridViewCellValueEventArgs) As String
        Return DataGridView1.Rows(cell.RowIndex).Cells( _
            ColumnName.EmployeeId.ToString()).Value().ToString()
    End Function

    Private Sub DataGridView1_CellValueNeeded(ByVal sender As Object, _
     ByVal e As DataGridViewCellValueEventArgs) _
        Handles DataGridView1.CellValueNeeded

        If IsCheckBoxColumn(e.ColumnIndex) Then
            Dim employeeId As String = GetKey(e)
            If Not inOffice.ContainsKey(employeeId) Then
                Dim defaultValue As Boolean = False
                inOffice.Add(employeeId, defaultValue)
            End If

            e.Value = inOffice.Item(employeeId)
        End If
    End Sub

    Private Function IsCheckBoxColumn(ByVal columnIndex As Integer) As Boolean

        Dim outOfOfficeColumn As DataGridViewColumn = _
            DataGridView1.Columns(ColumnName.OutOfOffice.ToString())
        Return (DataGridView1.Columns(columnIndex) Is outOfOfficeColumn)

    End Function
#End Region

End Class
C#
using System;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Drawing;

public class Employees : Form
{
    private DataGridView DataGridView1 = new DataGridView();
    private DataGridView DataGridView2 = new DataGridView();

    [STAThread]
    public static void Main()
    {
        try
        {
            Application.EnableVisualStyles();
            Application.Run(new Employees());
        }
        catch (Exception e)
        {
            MessageBox.Show(e.Message + e.StackTrace);
        }
    }

    public Employees()
    {
        this.Load += new EventHandler(Form1_Load);
    }

    private void Form1_Load(System.Object sender, System.EventArgs e)
    {
        try
        {
            SetUpForm();
            SetUpDataGridView1();
            SetUpDataGridView2();
        }
        catch (SqlException)
        {
            MessageBox.Show("The connection string <"
                + connectionString
                + "> failed to connect.  Modify it "
                + "to connect to a Northwind database accessible to "
                + "your system.",
                "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            Application.Exit();
        }
    }

    private void SetUpForm()
    {
        Size = new Size(800, 600);
        FlowLayoutPanel flowLayout = new FlowLayoutPanel();
        flowLayout.FlowDirection = FlowDirection.TopDown;
        flowLayout.Dock = DockStyle.Fill;
        Controls.Add(flowLayout);
        Text = "DataGridView columns demo";

        flowLayout.Controls.Add(DataGridView1);
        flowLayout.Controls.Add(DataGridView2);
    }

    private void SetUpDataGridView2()
    {
        DataGridView2.Dock = DockStyle.Bottom;
        DataGridView2.TopLeftHeaderCell.Value = "Sales Details";
        DataGridView2.RowHeadersWidthSizeMode = 
            DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders;
    }

    private void SetUpDataGridView1()
    {
        DataGridView1.DataError += new 
            DataGridViewDataErrorEventHandler(DataGridView1_DataError);
        DataGridView1.CellContentClick += new 
            DataGridViewCellEventHandler(DataGridView1_CellContentClick);
        DataGridView1.CellValuePushed += new 
            DataGridViewCellValueEventHandler(DataGridView1_CellValuePushed);
        DataGridView1.CellValueNeeded += new 
            DataGridViewCellValueEventHandler(DataGridView1_CellValueNeeded);

        // Virtual mode is turned on so that the
        // unbound DataGridViewCheckBoxColumn will
        // keep its state when the bound columns are
        // sorted.       
        DataGridView1.VirtualMode = true;
        DataGridView1.AutoSize = true;
        DataGridView1.DataSource = Populate("SELECT * FROM Employees");
        DataGridView1.TopLeftHeaderCell.Value = "Employees";
        DataGridView1.RowHeadersWidthSizeMode = 
            DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders;
        DataGridView1.ColumnHeadersHeightSizeMode = 
            DataGridViewColumnHeadersHeightSizeMode.AutoSize;
        DataGridView1.AutoSizeColumnsMode = 
            DataGridViewAutoSizeColumnsMode.AllCells;
        DataGridView1.AllowUserToAddRows = false;
        DataGridView1.AllowUserToDeleteRows = false;

        // The below autogenerated column is removed so 
        // a DataGridViewComboboxColumn could be used instead.
        DataGridView1.Columns.Remove(ColumnName.TitleOfCourtesy.ToString());
        DataGridView1.Columns.Remove(ColumnName.ReportsTo.ToString());

        AddLinkColumn();
        AddComboBoxColumns();
        AddButtonColumn();
        AddOutOfOfficeColumn();
    }

    // Using an enum provides some abstraction between column index
    // and column name along with compile time checking, and gives
    // a handy place to store the column names.
    enum ColumnName
    {
        EmployeeId,
        LastName,
        FirstName,
        Title,
        TitleOfCourtesy,
        BirthDate,
        HireDate,
        Address,
        City,
        Region,
        PostalCode,
        Country,
        HomePhone,
        Extension,
        Photo,
        Notes,
        ReportsTo,
        PhotoPath,
        OutOfOffice
    };

    private void AddComboBoxColumns()
    {
        DataGridViewComboBoxColumn comboboxColumn;
        comboboxColumn = CreateComboBoxColumn();
        SetAlternateChoicesUsingDataSource(comboboxColumn);
        comboboxColumn.HeaderText = "TitleOfCourtesy (via DataSource property)";
        DataGridView1.Columns.Insert(0, comboboxColumn);

        comboboxColumn = CreateComboBoxColumn();
        SetAlternateChoicesUsingItems(comboboxColumn);
        comboboxColumn.HeaderText = "TitleOfCourtesy (via Items property)";
        // Tack this example column onto the end.
        DataGridView1.Columns.Add(comboboxColumn);
    }

    private void AddLinkColumn()
    {
        DataGridViewLinkColumn links = new DataGridViewLinkColumn();

        links.HeaderText = ColumnName.ReportsTo.ToString();
        links.DataPropertyName = ColumnName.ReportsTo.ToString();
        links.ActiveLinkColor = Color.White;
        links.LinkBehavior = LinkBehavior.SystemDefault;
        links.LinkColor = Color.Blue;
        links.TrackVisitedState = true;
        links.VisitedLinkColor = Color.YellowGreen;

        DataGridView1.Columns.Add(links);
    }

    private static void SetAlternateChoicesUsingItems(
        DataGridViewComboBoxColumn comboboxColumn)
    {
        comboboxColumn.Items.AddRange("Mr.", "Ms.", "Mrs.", "Dr.");
    }

    private DataGridViewComboBoxColumn CreateComboBoxColumn()
    {
        DataGridViewComboBoxColumn column =
            new DataGridViewComboBoxColumn();
        {
            column.DataPropertyName = ColumnName.TitleOfCourtesy.ToString();
            column.HeaderText = ColumnName.TitleOfCourtesy.ToString();
            column.DropDownWidth = 160;
            column.Width = 90;
            column.MaxDropDownItems = 3;
            column.FlatStyle = FlatStyle.Flat;
        }
        return column;
    }

    private void SetAlternateChoicesUsingDataSource(DataGridViewComboBoxColumn comboboxColumn)
    {
        {
            comboboxColumn.DataSource = RetrieveAlternativeTitles();
            comboboxColumn.ValueMember = ColumnName.TitleOfCourtesy.ToString();
            comboboxColumn.DisplayMember = comboboxColumn.ValueMember;
        }
    }

    private DataTable RetrieveAlternativeTitles()
    {
        return Populate("SELECT distinct TitleOfCourtesy FROM Employees");
    }

    string connectionString =
        "Integrated Security=SSPI;Persist Security Info=False;" +
        "Initial Catalog=Northwind;Data Source=localhost";

    private DataTable Populate(string sqlCommand)
    {
        SqlConnection northwindConnection = new SqlConnection(connectionString);
        northwindConnection.Open();

        SqlCommand command = new SqlCommand(sqlCommand, northwindConnection);
        SqlDataAdapter adapter = new SqlDataAdapter();
        adapter.SelectCommand = command;

        DataTable table = new DataTable();
        table.Locale = System.Globalization.CultureInfo.InvariantCulture;
        adapter.Fill(table);

        return table;
    }

    private void AddButtonColumn()
    {
        DataGridViewButtonColumn buttons = new DataGridViewButtonColumn();
        {
            buttons.HeaderText = "Sales";
            buttons.Text = "Sales";
            buttons.UseColumnTextForButtonValue = true;
            buttons.AutoSizeMode =
                DataGridViewAutoSizeColumnMode.AllCells;
            buttons.FlatStyle = FlatStyle.Standard;
            buttons.CellTemplate.Style.BackColor = Color.Honeydew;
            buttons.DisplayIndex = 0;
        }

        DataGridView1.Columns.Add(buttons);

    }

    private void AddOutOfOfficeColumn()
    {
        DataGridViewCheckBoxColumn column = new DataGridViewCheckBoxColumn();
        {
            column.HeaderText = ColumnName.OutOfOffice.ToString();
            column.Name = ColumnName.OutOfOffice.ToString();
            column.AutoSizeMode = 
                DataGridViewAutoSizeColumnMode.DisplayedCells;
            column.FlatStyle = FlatStyle.Standard;
            column.ThreeState = true;
            column.CellTemplate = new DataGridViewCheckBoxCell();
            column.CellTemplate.Style.BackColor = Color.Beige;
        }

        DataGridView1.Columns.Insert(0, column);
    }

    private void PopulateSales(DataGridViewCellEventArgs buttonClick)
    {

        string employeeId = DataGridView1.Rows[buttonClick.RowIndex]
            .Cells[ColumnName.EmployeeId.ToString()].Value.ToString();
        DataGridView2.DataSource = Populate("SELECT * FROM Orders WHERE EmployeeId = " + employeeId);
    }

    #region "SQL Error handling"
    private void DataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs anError)
    {

        MessageBox.Show("Error happened " + anError.Context.ToString());

        if (anError.Context == DataGridViewDataErrorContexts.Commit)
        {
            MessageBox.Show("Commit error");
        }
        if (anError.Context == DataGridViewDataErrorContexts.CurrentCellChange)
        {
            MessageBox.Show("Cell change");
        }
        if (anError.Context == DataGridViewDataErrorContexts.Parsing)
        {
            MessageBox.Show("parsing error");
        }
        if (anError.Context == DataGridViewDataErrorContexts.LeaveControl)
        {
            MessageBox.Show("leave control error");
        }

        if ((anError.Exception) is ConstraintException)
        {
            DataGridView view = (DataGridView)sender;
            view.Rows[anError.RowIndex].ErrorText = "an error";
            view.Rows[anError.RowIndex].Cells[anError.ColumnIndex].ErrorText = "an error";

            anError.ThrowException = false;
        }
    }
    #endregion

    private void DataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {

        if (IsANonHeaderLinkCell(e))
        {
            MoveToLinked(e);
        }
        else if (IsANonHeaderButtonCell(e))
        {
            PopulateSales(e);
        }
    }

    private void MoveToLinked(DataGridViewCellEventArgs e)
    {
        string employeeId;
        object value = DataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
        if (value is DBNull) { return; }

        employeeId = value.ToString();
        DataGridViewCell boss = RetrieveSuperiorsLastNameCell(employeeId);
        if (boss != null)
        {
            DataGridView1.CurrentCell = boss;
        }
    }

    private bool IsANonHeaderLinkCell(DataGridViewCellEventArgs cellEvent)
    {
        if (DataGridView1.Columns[cellEvent.ColumnIndex] is
            DataGridViewLinkColumn &&
            cellEvent.RowIndex != -1)
        { return true; }
        else { return false; }
    }

    private bool IsANonHeaderButtonCell(DataGridViewCellEventArgs cellEvent)
    {
        if (DataGridView1.Columns[cellEvent.ColumnIndex] is
            DataGridViewButtonColumn &&
            cellEvent.RowIndex != -1)
        { return true; }
        else { return (false); }
    }

    private DataGridViewCell RetrieveSuperiorsLastNameCell(string employeeId)
    {

        foreach (DataGridViewRow row in DataGridView1.Rows)
        {
            if (row.IsNewRow) { return null; }
            if (row.Cells[ColumnName.EmployeeId.ToString()].Value.ToString().Equals(employeeId))
            {
                return row.Cells[ColumnName.LastName.ToString()];
            }
        }
        return null;
    }

    #region "checkbox state"
    Dictionary<string, bool> inOffice = new Dictionary<string, bool>();
    private void DataGridView1_CellValuePushed(object sender,
        DataGridViewCellValueEventArgs e)
    {
        if (IsCheckBoxColumn(e.ColumnIndex))
        {
            string employeeId = GetKey(e);
            if (!inOffice.ContainsKey(employeeId))
            {
                inOffice.Add(employeeId, (Boolean)e.Value);
            }
            else
            {
                inOffice[employeeId] = (Boolean)e.Value;
            }
        }
    }

    private string GetKey(DataGridViewCellValueEventArgs cell)
    {
        return DataGridView1.Rows[cell.RowIndex].
            Cells[ColumnName.EmployeeId.ToString()].Value.ToString();
    }

    private void DataGridView1_CellValueNeeded(object sender,
        DataGridViewCellValueEventArgs e)
    {

        if (IsCheckBoxColumn(e.ColumnIndex))
        {
            string employeeId = GetKey(e);
            if (!inOffice.ContainsKey(employeeId))
            {
                bool defaultValue = false;
                inOffice.Add(employeeId, defaultValue);
            }

            e.Value = inOffice[employeeId];
        }
    }

    private bool IsCheckBoxColumn(int columnIndex)
    {
        DataGridViewColumn outOfOfficeColumn =
            DataGridView1.Columns[ColumnName.OutOfOffice.ToString()];
        return (DataGridView1.Columns[columnIndex] == outOfOfficeColumn);
    }
    #endregion
}
Visual C++
#using <System.Data.dll>
#using <System.Windows.Forms.dll>
#using <System.dll>
#using <System.Drawing.dll>

#using <System.Xml.dll>
#using <System.EnterpriseServices.dll>
#using <System.Transactions.dll>
using namespace System;
using namespace System::Data;
using namespace System::Data::SqlClient;
using namespace System::Windows::Forms;
using namespace System::Collections::Generic;
using namespace System::Drawing;

public ref class Employees : public Form
{
private:
    DataGridView^ DataGridView1;

private:
    DataGridView^ DataGridView2;

public:
    [STAThread]
    static void Main()
    {
        try
        {
            Application::EnableVisualStyles();
            Application::Run(gcnew Employees());
        }
        catch (Exception^ e)
        {
            MessageBox::Show(e->Message + e->StackTrace);
        }
    }

private:
    Dictionary<String^, bool>^ inOffice;

public:
    Employees()
    {
        DataGridView1 = gcnew DataGridView();
        DataGridView2 = gcnew DataGridView();
        connectionString =
            "Integrated Security=SSPI;Persist Security Info=False;" +
            "Initial Catalog=Northwind;Data Source=localhost";
        inOffice = gcnew Dictionary<String^, bool>;

        this->Load += gcnew EventHandler(this, &Employees::Form1_Load);
    }

private:
    void Form1_Load(System::Object^ /*sender*/, System::EventArgs^ /*e*/)
    {
        try
        {
            SetUpForm();
            SetUpDataGridView1();
            SetUpDataGridView2();
        }
        catch (SqlException^)
        {
            MessageBox::Show("The connection string <"
                + connectionString
                + "> failed to connect.  Modify it "
                + "to connect to a Northwind database accessible to "
                + "your system.",
                "ERROR", MessageBoxButtons::OK, MessageBoxIcon::Exclamation);
            Application::Exit();
        }
    }

private:
    void SetUpForm()
    {
        Size = System::Drawing::Size(800, 600);
        FlowLayoutPanel^ flowLayout = gcnew FlowLayoutPanel();
        flowLayout->FlowDirection = FlowDirection::TopDown;
        flowLayout->Dock = DockStyle::Fill;
        Controls->Add(flowLayout);

        flowLayout->Controls->Add(DataGridView1);
        flowLayout->Controls->Add(DataGridView2);
    }

private:
    void SetUpDataGridView2()
    {
        DataGridView2->Dock = DockStyle::Bottom;
        DataGridView2->TopLeftHeaderCell->Value = "Sales Details";
        DataGridView2->RowHeadersWidthSizeMode = 
            DataGridViewRowHeadersWidthSizeMode::AutoSizeToAllHeaders;
    }

private:
    void SetUpDataGridView1()
    {
        //DataGridView1.DataError += new 
          //  DataGridViewDataErrorEventHandler(DataGridView1_DataError);
        DataGridView1->CellContentClick += gcnew 
            DataGridViewCellEventHandler(this, &Employees::DataGridView1_CellContentClick);
        DataGridView1->CellValuePushed += gcnew 
            DataGridViewCellValueEventHandler(this, &Employees::DataGridView1_CellValuePushed);
        DataGridView1->CellValueNeeded += gcnew 
            DataGridViewCellValueEventHandler(this, &Employees::DataGridView1_CellValueNeeded);

        // Virtual mode is turned on so that the
        // unbound DataGridViewCheckBoxColumn will
        // keep its state when the bound columns are
        // sorted.       
        DataGridView1->VirtualMode = true;
        DataGridView1->AutoSize = true;
        DataGridView1->DataSource = Populate("SELECT * FROM Employees");
        DataGridView1->TopLeftHeaderCell->Value = "Employees";
        DataGridView1->RowHeadersWidthSizeMode = 
            DataGridViewRowHeadersWidthSizeMode::AutoSizeToAllHeaders;
        DataGridView1->ColumnHeadersHeightSizeMode = 
            DataGridViewColumnHeadersHeightSizeMode::AutoSize;
        DataGridView1->AutoSizeColumnsMode = 
            DataGridViewAutoSizeColumnsMode::AllCells;
        DataGridView1->AllowUserToAddRows = false;
        DataGridView1->AllowUserToDeleteRows = false;

        // The below autogenerated column is removed so 
        // a DataGridViewComboboxColumn could be used instead.
        DataGridView1->Columns->Remove(ColumnName::TitleOfCourtesy.ToString());
        DataGridView1->Columns->Remove(ColumnName::ReportsTo.ToString());

        AddLinkColumn();
        AddComboBoxColumns();
        AddButtonColumn();
        AddOutOfOfficeColumn();
    }

    // Using an enum provides some abstraction between column index
    // and column name along with compile time checking, and gives
    // a handy place to store the column names.
    enum class ColumnName
    {
        EmployeeID,
        LastName,
        FirstName,
        Title,
        TitleOfCourtesy,
        BirthDate,
        HireDate,
        Address,
        City,
        Region,
        PostalCode,
        Country,
        HomePhone,
        Extension,
        Photo,
        Notes,
        ReportsTo,
        PhotoPath,
        OutOfOffice
    };

private:
    void AddComboBoxColumns()
    {
        DataGridViewComboBoxColumn^ comboboxColumn;
        comboboxColumn = CreateComboBoxColumn();
        SetAlternateChoicesUsingDataSource(comboboxColumn);
        comboboxColumn->HeaderText = "TitleOfCourtesy (via DataSource property)";
        DataGridView1->Columns->Insert(0, comboboxColumn);

        comboboxColumn = CreateComboBoxColumn();
        SetAlternateChoicesUsingItems(comboboxColumn);
        comboboxColumn->HeaderText = "TitleOfCourtesy (via Items property)";
        // Tack this example column onto the end.
        DataGridView1->Columns->Add(comboboxColumn);
    }

private:
    void AddLinkColumn()
    {
        DataGridViewLinkColumn^ links = gcnew DataGridViewLinkColumn();

        links->HeaderText = ColumnName::ReportsTo.ToString();
        links->DataPropertyName = ColumnName::ReportsTo.ToString();
        links->ActiveLinkColor = Color::White;
        links->LinkBehavior = LinkBehavior::SystemDefault;
        links->LinkColor = Color::Blue;
        links->TrackVisitedState = true;
        links->VisitedLinkColor = Color::YellowGreen;

        DataGridView1->Columns->Add(links);
    }

private:
    void SetAlternateChoicesUsingItems(
        DataGridViewComboBoxColumn^ comboboxColumn)
    {
        comboboxColumn->Items->AddRange("Mr.", "Ms.", "Mrs.", "Dr.");
    }

private:
    DataGridViewComboBoxColumn^ CreateComboBoxColumn()
    {
        DataGridViewComboBoxColumn^ column =
            gcnew DataGridViewComboBoxColumn();
        {
            column->DataPropertyName = ColumnName::TitleOfCourtesy.ToString();
            column->HeaderText = ColumnName::TitleOfCourtesy.ToString();
            column->DropDownWidth = 160;
            column->Width = 90;
            column->MaxDropDownItems = 3;
            column->FlatStyle = FlatStyle::Flat;
        }
        return column;
    }

private:
    void SetAlternateChoicesUsingDataSource(DataGridViewComboBoxColumn^ comboboxColumn)
    {
        {
            comboboxColumn->DataSource = RetrieveAlternativeTitles();
            comboboxColumn->ValueMember = ColumnName::TitleOfCourtesy.ToString();
            comboboxColumn->DisplayMember = comboboxColumn->ValueMember;
        }
    }

private:
    DataTable^ RetrieveAlternativeTitles()
    {
        return Populate("SELECT distinct TitleOfCourtesy FROM Employees");
    }

    String^ connectionString;

private:
    DataTable^ Populate(String^ sqlCommand)
    {
        SqlConnection^ northwindConnection = gcnew SqlConnection(connectionString);
        northwindConnection->Open();

        SqlCommand^ command = gcnew SqlCommand(sqlCommand, northwindConnection);
        SqlDataAdapter^ adapter = gcnew SqlDataAdapter();
        adapter->SelectCommand = command;

        DataTable^ table = gcnew DataTable();
        adapter->Fill(table);

        return table;
    }

private:
    void AddButtonColumn()
    {
        DataGridViewButtonColumn^ buttons = gcnew DataGridViewButtonColumn();
        {
            buttons->HeaderText = "Sales";
            buttons->Text = "Sales";
            buttons->UseColumnTextForButtonValue = true;
            buttons->AutoSizeMode =
                DataGridViewAutoSizeColumnMode::AllCells;
            buttons->FlatStyle = FlatStyle::Standard;
            buttons->CellTemplate->Style->BackColor = Color::Honeydew;
            buttons->DisplayIndex = 0;
        }

        DataGridView1->Columns->Add(buttons);

    }

private:
    void AddOutOfOfficeColumn()
    {
        DataGridViewCheckBoxColumn^ column = gcnew DataGridViewCheckBoxColumn();
        {
            column->HeaderText = ColumnName::OutOfOffice.ToString();
            column->Name = ColumnName::OutOfOffice.ToString();
            column->AutoSizeMode = 
                DataGridViewAutoSizeColumnMode::DisplayedCells;
            column->FlatStyle = FlatStyle::Standard;
            column->ThreeState = true;
            column->CellTemplate = gcnew DataGridViewCheckBoxCell();
            column->CellTemplate->Style->BackColor = Color::Beige;
        }

        DataGridView1->Columns->Insert(0, column);
    }

private:
    void PopulateSales(DataGridViewCellEventArgs^ buttonClick)
    {

        String^ employeeID = DataGridView1->Rows[buttonClick->RowIndex]
            ->Cells[ColumnName::EmployeeID.ToString()]->Value->ToString();
        DataGridView2->DataSource = Populate("SELECT * FROM Orders WHERE EmployeeID = " + employeeID);
    }

    #pragma region "SQL Error handling"
private:
    void DataGridView1_DataError(Object^ sender, DataGridViewDataErrorEventArgs^ anError)
    {

        MessageBox::Show("Error happened " + anError->Context.ToString());

        if (anError->Context == DataGridViewDataErrorContexts::Commit)
        {
            MessageBox::Show("Commit error");
        }
        if (anError->Context == DataGridViewDataErrorContexts::CurrentCellChange)
        {
            MessageBox::Show("Cell change");
        }
        if (anError->Context == DataGridViewDataErrorContexts::Parsing)
        {
            MessageBox::Show("parsing error");
        }
        if (anError->Context == DataGridViewDataErrorContexts::LeaveControl)
        {
            MessageBox::Show("leave control error");
        }

        if (dynamic_cast<ConstraintException^>(anError->Exception) != nullptr)
        {
            DataGridView^ view = (DataGridView^)sender;
            view->Rows[anError->RowIndex]->ErrorText = "an error";
            view->Rows[anError->RowIndex]->Cells[anError->ColumnIndex]->ErrorText = "an error";

            anError->ThrowException = false;
        }
    }
    #pragma endregion

private:
    void DataGridView1_CellContentClick(Object^ /*sender*/, DataGridViewCellEventArgs^ e)
    {

        if (IsANonHeaderLinkCell(e))
        {
            MoveToLinked(e);
        }
        else if (IsANonHeaderButtonCell(e))
        {
            PopulateSales(e);
        }
    }

private:
    void MoveToLinked(DataGridViewCellEventArgs^ e)
    {
        String^ employeeId;
        Object^ value = DataGridView1->Rows[e->RowIndex]->Cells[e->ColumnIndex]->Value;
        if (dynamic_cast<DBNull^>(value) != nullptr) { return; }

        employeeId = value->ToString();
        DataGridViewCell^ boss = RetrieveSuperiorsLastNameCell(employeeId);
        if (boss != nullptr)
        {
            DataGridView1->CurrentCell = boss;
        }
    }

private:
    bool IsANonHeaderLinkCell(DataGridViewCellEventArgs^ cellEvent)
    {
        if (dynamic_cast<DataGridViewLinkColumn^>(DataGridView1->Columns[cellEvent->ColumnIndex]) != nullptr
             &&
            cellEvent->RowIndex != -1)
        { return true; }
        else { return false; }
    }

private:
    bool IsANonHeaderButtonCell(DataGridViewCellEventArgs^ cellEvent)
    {
        if (dynamic_cast<DataGridViewButtonColumn^>(DataGridView1->Columns[cellEvent->ColumnIndex]) != nullptr
             &&
            cellEvent->RowIndex != -1)
        { return true; }
        else { return (false); }
    }

private:
    DataGridViewCell^ RetrieveSuperiorsLastNameCell(String^ employeeId)
    {

        for each (DataGridViewRow^ row in DataGridView1->Rows)
        {
            if (row->IsNewRow) { return nullptr; }
            if (row->Cells[ColumnName::EmployeeID.ToString()]->Value->ToString()->Equals(employeeId))
            {
                return row->Cells[ColumnName::LastName.ToString()];
            }
        }
        return nullptr;
    }

    #pragma region "checkbox state"

private:
    void DataGridView1_CellValuePushed(Object^ sender,
        DataGridViewCellValueEventArgs^ e)
    {
        if (IsCheckBoxColumn(e->ColumnIndex))
        {
            String^ employeeId = GetKey(e);
            if (!inOffice->ContainsKey(employeeId))
            {
                inOffice->Add(employeeId, (Boolean)e->Value);
            }
            else
            {
                inOffice[employeeId] = (Boolean)e->Value;
            }
        }
    }

private:
    String^ GetKey(DataGridViewCellValueEventArgs^ cell)
    {
        return DataGridView1->Rows[cell->RowIndex]->
            Cells[ColumnName::EmployeeID.ToString()]->Value->ToString();
    }

private:
    void DataGridView1_CellValueNeeded(Object^ sender,
        DataGridViewCellValueEventArgs^ e)
    {

        if (IsCheckBoxColumn(e->ColumnIndex))
        {
            String^ employeeId = GetKey(e);
            if (!inOffice->ContainsKey(employeeId))
            {
                bool defaultValue = false;
                inOffice->Add(employeeId, defaultValue);
            }

            e->Value = inOffice[employeeId];
        }
    }

private:
    bool IsCheckBoxColumn(int columnIndex)
    {
        DataGridViewColumn^ outOfOfficeColumn =
            DataGridView1->Columns[ColumnName::OutOfOffice.ToString()];
        return (DataGridView1->Columns[columnIndex] == outOfOfficeColumn);
    }
    #pragma endregion
};

int main()
{
    Employees::Main();
}
Todos los miembros static (Shared en Visual Basic) públicos de este tipo son seguros para la ejecución de subprocesos. No se garantiza que los miembros de instancias sean seguros para la ejecución de subprocesos.

Windows Vista, Windows XP SP2, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP Starter Edition, Windows Server 2003, Windows Server 2000 SP4, Windows Millennium Edition, Windows 98

.NET Framework y .NET Compact Framework no admiten todas las versiones de cada plataforma. Para obtener una lista de las versiones compatibles, vea Requisitos de sistema de .NET Framework.

.NET Framework

Compatible con: 3.5, 3.0, 2.0
Contenido de la comunidad   ¿Qué es Community Content?
Agregar contenido nuevo RSS  Anotaciones
Processing
© 2012 Microsoft. Reservados todos los derechos. Términos de uso | Marcas Registradas | Privacidad
Page view tracker