DataGridViewComboBoxCell无法正常工作 [英] DataGridViewComboBoxCell not working right

查看:90
本文介绍了DataGridViewComboBoxCell无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在下面有一个非常简单的示例应用程序。这适用于Windows窗体,并且应该具有在Designer中创建的匹配,其中DataGridView具有两列:Name和Department。 Department是一个DataGridViewComboBoxCell。



网格按预期列出数据,组合框按预期列出其项目。但是,我无法将组合框中选择的数据绑定到网格的DataBoundItem。例如,当应用程序首次启动时,我唯一的Person对象具有DepartmentID = 2,它与组合框中的值匹配,但在组合框中未选择任何内容。当在组合框中选择了某些内容时,它不会反映在Person对象中。



有一条注释掉的代码行用于设置ValueMember,但是这会导致不存在名为DeptID的字段错误。



两个数据集都是ArrayList而不是DataTable非常重要。



如何完成行数据和组合框选择之间的绑定?



---完整的项目代码如下---



I have a very simple sample application below. This is for Windows Forms, and should have a matching for created in Designer with a DataGridView that has two columns: Name, and Department. Department is a DataGridViewComboBoxCell.

The grid lists data as expected, and the combo-box list its items as expected. However, I cannot get the data selected in the combo-box tied to the DataBoundItem of the grid. For example, when the app first starts, my only Person object has a DepartmentID = 2, which matches a value in the combo-box, but nothing is selected in the combo-box. When something is selected in the combo-box, it does not get reflected in the Person object.

There is a commented-out line of code for setting ValueMember, but this causes a "Field called DeptID does not exist" error.

It is important that both data sets are ArrayList and not DataTable.

How do I complete the binding between row data and combo-box selection?

--- Full project code is below ---

using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace TestApp
{
	public partial class Form1 : Form
	{
		private ArrayList personList = new ArrayList();
		private ArrayList deptList = new ArrayList();
		BindingSource m_BindSource = new BindingSource();
		public Form1()
		{
			InitializeComponent();
		}
		private void Form1_Load(object sender, EventArgs e)
		{
			personList.Add(new Person("Tim", 2));
			deptList.Add(new Department("A", 1));
			deptList.Add(new Department("B", 2));
			deptList.Add(new Department("C", 3));
			DataGridViewComboBoxCell cell = (DataGridViewComboBoxCell)grid1.Columns[1].CellTemplate;
			cell.DataSource = deptList;
			cell.DisplayMember = "DeptName";
			//cell.ValueMember = "DeptID";	// "Field called DeptID does not exist"
			try
			{
				m_BindSource.DataSource = null;
				m_BindSource.DataSource = personList;
				grid1.DataSource = m_BindSource;
			}
			catch (Exception ex)
			{
				ex.GetType();
				MessageBox.Show(ex.Message);
			}
		}
	}
	public class Person
	{
		public Person(String name, int deptID)
		{
			PersonName = name;
			DepartmentID = deptID;
		}
		private String m_PersonName;
		public String PersonName
		{
			get { return m_PersonName; }
			set { m_PersonName = value; }
		}
		private int m_DepartmentID;
		public int DepartmentID
		{
			get { return m_DepartmentID; }
			set { m_DepartmentID = value; }
		}
	}
	public class Department
	{
		public Department(String name, int deptID)
		{
			DeptName = name;
			DepartmentID = deptID;
		}
		private String m_DeptName;
		public String DeptName
		{
			get { return m_DeptName; }
			set { m_DeptName = value; }
		}
		private int m_DepartmentID;
		public int DepartmentID
		{
			get { return m_DepartmentID; }
			set { m_DepartmentID = value; }
		}
	}
}

推荐答案

经过大量研究和修补,我找到了解决方案。下面是Form1_Load()的主体。该解决方案分为两部分:



1)不要动态创建单元格/列,只需将其构建到设计时视图中并适当绑定为如下所示:catch()语句



2)网格不会像我习惯的那样自动将行数据与组合框数据进行匹配。最后的for循环遍历并将现有的行数据选择绑定到组合框中的相应条目。



作为补充说明,我发现这个解决方案如果DataGridView位于选项卡控件中,则会出现其他问题。如果网格位于第一个选项卡以外的任何选项卡上,则行/组合框绑定将失败。这是否是一个MS错误我不知道,但解决方案是将for循环放在选项卡控件的SelectedIndexChanged()事件中的下面的代码中,并在更改为相关选项卡时运行它。 br $>


After much research and tinkering, I found the solution. Below is the body of Form1_Load() that works. There are two parts to the solution:

1) Instead of creating the cell/column on the fly, just build it into the design-time view and bind appropriately as shown below the catch() statement

2) The grid will not automatically match up row data with combobox data as I am used to. The for-loop at the end goes through and binds the existing row data selection to the corresponding entry in the combobox.

As an additional note, I found that this solution has additional problems if the DataGridView is located in a tab control. If the grid is on any tab other than the first one, the row/combobox binding will fail. Whether this is a MS bug or not I don't know, but the solution was to put the for-loop in the code below in the SelectedIndexChanged() event for the tab control and run it when changing to the tab in question.

personList.Add(new Person("Tim", 2));   // Create one Person data object and add it to the list used by the DataGridView

// Create a list of Departments to be used by the combo box in the DataGridView
deptList.Add(new Department("A", 1));
deptList.Add(new Department("B", 2));
deptList.Add(new Department("C", 3));

grid1.AutoGenerateColumns = false;  // If we don't do this, the DepartmentID shows up as an additional column

try // Bind the Person list to the DataGridView
{
    m_BindSource.DataSource = null;
    m_BindSource.DataSource = personList;
    grid1.DataSource = m_BindSource;
}
catch (Exception ex)
{
    ex.GetType();
    MessageBox.Show(ex.Message);
}

// Bind the Department data to the appropriate column in the DataGridView
((DataGridViewComboBoxColumn)grid1.Columns["Department"]).DataSource = deptList;
((DataGridViewComboBoxColumn)grid1.Columns["Department"]).DisplayMember = "DeptName";
((DataGridViewComboBoxColumn)grid1.Columns["Department"]).ValueMember = "DeptID";

// Since the DataGridView won't automatically sync the Department list with each Person's DepartmentID, we have to manually link the two. This is what
// causes the combo box to show the proper selection for each Person's Department in the grid of existing data.
foreach (DataGridViewRow row in grid1.Rows)
{
    if (row.DataBoundItem != null)
    {
        row.Cells["Department"].Value = ((Person)row.DataBoundItem).DepartmentID;
    }
}


这篇关于DataGridViewComboBoxCell无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆