如何:访问 Windows 窗体 DataGridViewComboBoxCell 下拉列表中的对象
与 ComboBox 控件一样,DataGridViewComboBoxColumn 和 DataGridViewComboBoxCell 类型可用于将任意对象添加到其下拉列表中。 使用此功能,可以在下拉列表中表示复杂状态,而无需将相应的对象存储在单独的集合中。
与 ComboBox 控件不同,DataGridView 类型没有用于检索当前选定对象的 SelectedItem 属性。 相反,必须将 DataGridViewComboBoxColumn.ValueMember 或 DataGridViewComboBoxCell.ValueMember 属性设置为业务对象上的属性名称。 当用户进行选择时,业务对象的指示属性将设置单元格 Value 属性。
若要通过单元格值检索业务对象,ValueMember
属性必须指示返回对业务对象本身的引用的属性。 因此,如果业务对象的类型不在你的控制范围之下,则必须通过继承扩展类型来添加此类属性。
以下过程演示如何使用业务对象填充下拉列表,并通过单元格 Value 属性检索对象。
将业务对象添加到下拉列表
创建一个新的 DataGridViewComboBoxColumn 并填充其 Items 集合。 或者,可以将列 DataSource 属性设置为业务对象的集合。 但是,在这种情况下,如果不在集合中创建相应的业务对象,就无法将“未分配”添加到下拉列表中。
DataGridViewComboBoxColumn assignedToColumn = new DataGridViewComboBoxColumn(); // Populate the combo box drop-down list with Employee objects. foreach (Employee e in employees) assignedToColumn.Items.Add(e); // Add "unassigned" to the drop-down list and display it for // empty AssignedTo values or when the user presses CTRL+0. assignedToColumn.Items.Add("unassigned"); assignedToColumn.DefaultCellStyle.NullValue = "unassigned";
Dim assignedToColumn As New DataGridViewComboBoxColumn() ' Populate the combo box drop-down list with Employee objects. For Each e As Employee In employees assignedToColumn.Items.Add(e) Next ' Add "unassigned" to the drop-down list and display it for ' empty AssignedTo values or when the user presses CTRL+0. assignedToColumn.Items.Add("unassigned") assignedToColumn.DefaultCellStyle.NullValue = "unassigned"
设置 DisplayMember 和 ValueMember 属性。 DisplayMember 表示要在下拉列表中显示的业务对象的属性。 ValueMember 表示返回对业务对象的引用的属性。
assignedToColumn.DisplayMember = "Name"; assignedToColumn.ValueMember = "Self";
assignedToColumn.DisplayMember = "Name" assignedToColumn.ValueMember = "Self"
请确保业务对象类型包含返回对当前实例的引用的属性。 必须使用在上一步中分配给 ValueMember 的值为此属性命名。
public Employee Self { get { return this; } }
Public ReadOnly Property Self() As Employee Get Return Me End Get End Property
检索当前选定的业务对象
获取单元格 Value 属性并将其转换为业务对象类型。
// Retrieve the Employee object from the "Assigned To" cell. Employee assignedTo = dataGridView1.Rows[e.RowIndex] .Cells["Assigned To"].Value as Employee;
' Retrieve the Employee object from the "Assigned To" cell. Dim assignedTo As Employee = TryCast(dataGridView1.Rows(e.RowIndex) _ .Cells("Assigned To").Value, Employee)
示例
完整的示例演示了下拉列表中业务对象的使用。 在示例中,DataGridView 控件绑定到 Task
对象的集合。 每个 Task
对象都有一个 AssignedTo
属性,该属性指示当前分配给该任务的 Employee
对象。 Assigned To
列显示每个已分配员工的 Name
属性值,如果 Task.AssignedTo
属性值为 null
,则显示“未分配”。
若要查看此示例的行为,请执行以下步骤:
通过从下拉列表中选择不同的值或在组合框单元格中按 CTRL+0 来更改
Assigned To
列中的分配。单击
Generate Report
显示当前分配。 这表明Assigned To
列中的更改会自动更新tasks
集合。单击
Request Status
按钮以调用该行的当前Employee
对象的RequestStatus
方法。 这表明已成功检索到选定对象。
using System;
using System.Text;
using System.Collections.Generic;
using System.Windows.Forms;
public class Form1 : Form
{
private List<Employee> employees = new List<Employee>();
private List<Task> tasks = new List<Task>();
private Button reportButton = new Button();
private DataGridView dataGridView1 = new DataGridView();
[STAThread]
public static void Main()
{
Application.Run(new Form1());
}
public Form1()
{
dataGridView1.Dock = DockStyle.Fill;
dataGridView1.AutoSizeColumnsMode =
DataGridViewAutoSizeColumnsMode.AllCells;
reportButton.Text = "Generate Report";
reportButton.Dock = DockStyle.Top;
reportButton.Click += new EventHandler(reportButton_Click);
Controls.Add(dataGridView1);
Controls.Add(reportButton);
Load += new EventHandler(Form1_Load);
Text = "DataGridViewComboBoxColumn Demo";
}
// Initializes the data source and populates the DataGridView control.
private void Form1_Load(object sender, EventArgs e)
{
PopulateLists();
dataGridView1.AutoGenerateColumns = false;
dataGridView1.DataSource = tasks;
AddColumns();
}
// Populates the employees and tasks lists.
private void PopulateLists()
{
employees.Add(new Employee("Harry"));
employees.Add(new Employee("Sally"));
employees.Add(new Employee("Roy"));
employees.Add(new Employee("Pris"));
tasks.Add(new Task(1, employees[1]));
tasks.Add(new Task(2));
tasks.Add(new Task(3, employees[2]));
tasks.Add(new Task(4));
}
// Configures columns for the DataGridView control.
private void AddColumns()
{
DataGridViewTextBoxColumn idColumn =
new DataGridViewTextBoxColumn();
idColumn.Name = "Task";
idColumn.DataPropertyName = "Id";
idColumn.ReadOnly = true;
DataGridViewComboBoxColumn assignedToColumn =
new DataGridViewComboBoxColumn();
// Populate the combo box drop-down list with Employee objects.
foreach (Employee e in employees) assignedToColumn.Items.Add(e);
// Add "unassigned" to the drop-down list and display it for
// empty AssignedTo values or when the user presses CTRL+0.
assignedToColumn.Items.Add("unassigned");
assignedToColumn.DefaultCellStyle.NullValue = "unassigned";
assignedToColumn.Name = "Assigned To";
assignedToColumn.DataPropertyName = "AssignedTo";
assignedToColumn.AutoComplete = true;
assignedToColumn.DisplayMember = "Name";
assignedToColumn.ValueMember = "Self";
// Add a button column.
DataGridViewButtonColumn buttonColumn =
new DataGridViewButtonColumn();
buttonColumn.HeaderText = "";
buttonColumn.Name = "Status Request";
buttonColumn.Text = "Request Status";
buttonColumn.UseColumnTextForButtonValue = true;
dataGridView1.Columns.Add(idColumn);
dataGridView1.Columns.Add(assignedToColumn);
dataGridView1.Columns.Add(buttonColumn);
// Add a CellClick handler to handle clicks in the button column.
dataGridView1.CellClick +=
new DataGridViewCellEventHandler(dataGridView1_CellClick);
}
// Reports on task assignments.
private void reportButton_Click(object sender, EventArgs e)
{
StringBuilder report = new StringBuilder();
foreach (Task t in tasks)
{
String assignment =
t.AssignedTo == null ?
"unassigned" : "assigned to " + t.AssignedTo.Name;
report.AppendFormat("Task {0} is {1}.", t.Id, assignment);
report.Append(Environment.NewLine);
}
MessageBox.Show(report.ToString(), "Task Assignments");
}
// Calls the Employee.RequestStatus method.
void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
// Ignore clicks that are not on button cells.
if (e.RowIndex < 0 || e.ColumnIndex !=
dataGridView1.Columns["Status Request"].Index) return;
// Retrieve the task ID.
Int32 taskID = (Int32)dataGridView1[0, e.RowIndex].Value;
// Retrieve the Employee object from the "Assigned To" cell.
Employee assignedTo = dataGridView1.Rows[e.RowIndex]
.Cells["Assigned To"].Value as Employee;
// Request status through the Employee object if present.
if (assignedTo != null)
{
assignedTo.RequestStatus(taskID);
}
else
{
MessageBox.Show(String.Format(
"Task {0} is unassigned.", taskID), "Status Request");
}
}
}
public class Task
{
public Task(Int32 id)
{
idValue = id;
}
public Task(Int32 id, Employee assignedTo)
{
idValue = id;
assignedToValue = assignedTo;
}
private Int32 idValue;
public Int32 Id
{
get { return idValue; }
set { idValue = value; }
}
private Employee assignedToValue;
public Employee AssignedTo
{
get { return assignedToValue; }
set { assignedToValue = value; }
}
}
public class Employee
{
public Employee(String name)
{
nameValue = name;
}
private String nameValue;
public String Name
{
get { return nameValue; }
set { nameValue = value; }
}
public Employee Self
{
get { return this; }
}
public void RequestStatus(Int32 taskID)
{
MessageBox.Show(String.Format(
"Status for task {0} has been requested from {1}.",
taskID, nameValue), "Status Request");
}
}
Imports System.Text
Imports System.Collections.Generic
Imports System.Windows.Forms
Public Class Form1
Inherits Form
Private employees As New List(Of Employee)
Private tasks As New List(Of Task)
Private WithEvents reportButton As New Button
Private WithEvents dataGridView1 As New DataGridView
<STAThread()> _
Public Sub Main()
Application.Run(New Form1)
End Sub
Sub New()
dataGridView1.Dock = DockStyle.Fill
dataGridView1.AutoSizeColumnsMode = _
DataGridViewAutoSizeColumnsMode.AllCells
reportButton.Text = "Generate Report"
reportButton.Dock = DockStyle.Top
Controls.Add(dataGridView1)
Controls.Add(reportButton)
Text = "DataGridViewComboBoxColumn Demo"
End Sub
' Initializes the data source and populates the DataGridView control.
Private Sub Form1_Load(ByVal sender As Object, _
ByVal e As EventArgs) Handles Me.Load
PopulateLists()
dataGridView1.AutoGenerateColumns = False
dataGridView1.DataSource = tasks
AddColumns()
End Sub
' Populates the employees and tasks lists.
Private Sub PopulateLists()
employees.Add(New Employee("Harry"))
employees.Add(New Employee("Sally"))
employees.Add(New Employee("Roy"))
employees.Add(New Employee("Pris"))
tasks.Add(New Task(1, employees(1)))
tasks.Add(New Task(2))
tasks.Add(New Task(3, employees(2)))
tasks.Add(New Task(4))
End Sub
' Configures columns for the DataGridView control.
Private Sub AddColumns()
Dim idColumn As New DataGridViewTextBoxColumn()
idColumn.Name = "Task"
idColumn.DataPropertyName = "Id"
idColumn.ReadOnly = True
Dim assignedToColumn As New DataGridViewComboBoxColumn()
' Populate the combo box drop-down list with Employee objects.
For Each e As Employee In employees
assignedToColumn.Items.Add(e)
Next
' Add "unassigned" to the drop-down list and display it for
' empty AssignedTo values or when the user presses CTRL+0.
assignedToColumn.Items.Add("unassigned")
assignedToColumn.DefaultCellStyle.NullValue = "unassigned"
assignedToColumn.Name = "Assigned To"
assignedToColumn.DataPropertyName = "AssignedTo"
assignedToColumn.AutoComplete = True
assignedToColumn.DisplayMember = "Name"
assignedToColumn.ValueMember = "Self"
' Add a button column.
Dim buttonColumn As New DataGridViewButtonColumn()
buttonColumn.HeaderText = ""
buttonColumn.Name = "Status Request"
buttonColumn.Text = "Request Status"
buttonColumn.UseColumnTextForButtonValue = True
dataGridView1.Columns.Add(idColumn)
dataGridView1.Columns.Add(assignedToColumn)
dataGridView1.Columns.Add(buttonColumn)
End Sub
' Reports on task assignments.
Private Sub reportButton_Click(ByVal sender As Object, _
ByVal e As EventArgs) Handles reportButton.Click
Dim report As New StringBuilder()
For Each t As Task In tasks
Dim assignment As String
If t.AssignedTo Is Nothing Then
assignment = "unassigned"
Else
assignment = "assigned to " + t.AssignedTo.Name
End If
report.AppendFormat("Task {0} is {1}.", t.Id, assignment)
report.Append(Environment.NewLine)
Next
MessageBox.Show(report.ToString(), "Task Assignments")
End Sub
' Calls the Employee.RequestStatus method.
Private Sub dataGridView1_CellClick(ByVal sender As Object, _
ByVal e As DataGridViewCellEventArgs) _
Handles dataGridView1.CellClick
' Ignore clicks that are not on button cells.
If e.RowIndex < 0 OrElse Not e.ColumnIndex = _
dataGridView1.Columns("Status Request").Index Then Return
' Retrieve the task ID.
Dim taskID As Int32 = CInt(dataGridView1(0, e.RowIndex).Value)
' Retrieve the Employee object from the "Assigned To" cell.
Dim assignedTo As Employee = TryCast(dataGridView1.Rows(e.RowIndex) _
.Cells("Assigned To").Value, Employee)
' Request status through the Employee object if present.
If assignedTo IsNot Nothing Then
assignedTo.RequestStatus(taskID)
Else
MessageBox.Show(String.Format( _
"Task {0} is unassigned.", taskID), "Status Request")
End If
End Sub
End Class
Public Class Task
Sub New(ByVal id As Int32)
idValue = id
End Sub
Sub New(ByVal id As Int32, ByVal assignedTo As Employee)
idValue = id
assignedToValue = assignedTo
End Sub
Private idValue As Int32
Public Property Id() As Int32
Get
Return idValue
End Get
Set(ByVal value As Int32)
idValue = value
End Set
End Property
Private assignedToValue As Employee
Public Property AssignedTo() As Employee
Get
Return assignedToValue
End Get
Set(ByVal value As Employee)
assignedToValue = value
End Set
End Property
End Class
Public Class Employee
Sub New(ByVal name As String)
nameValue = name
End Sub
Private nameValue As String
Public Property Name() As String
Get
Return nameValue
End Get
Set(ByVal value As String)
nameValue = value
End Set
End Property
Public ReadOnly Property Self() As Employee
Get
Return Me
End Get
End Property
Public Sub RequestStatus(ByVal taskID As Int32)
MessageBox.Show(String.Format( _
"Status for task {0} has been requested from {1}.", _
taskID, nameValue), "Status Request")
End Sub
End Class
编译代码
此示例需要:
- 对 System 和 System.Windows.Forms 程序集的引用。
另请参阅
- DataGridView
- DataGridViewComboBoxColumn
- DataGridViewComboBoxColumn.Items
- DataGridViewComboBoxColumn.DataSource
- DataGridViewComboBoxColumn.ValueMember
- DataGridViewComboBoxCell
- DataGridViewComboBoxCell.Items
- DataGridViewComboBoxCell.DataSource
- DataGridViewComboBoxCell.ValueMember
- DataGridViewCell.Value
- ComboBox
- 在 Windows 窗体 DataGridView 控件中显示数据
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈