我们在客户端程序的设计中经常会用到组合下拉框,就像这种情况
我在项目中想用datagridview来实现这种功能,看了若干博客,msdn也翻了半天,终于有了一点理解。
这里有几个关键点:
1、datagridview控件的列的类型有多重,包括
(1)DataGridViewTextBoxColumn(文本列,默认的情况下就是这种)
(2)DataGridViewComboBoxColumn(组合框列,名字瞎起的,就是这个功能要用到的列)
(3)DataGridViewLinkColumn(链接列)
(4)DataGridViewButtonColumn(按钮列)
(5)DataGridViewCheckBoxColumn(打钩列?差不多这个意思)
我想要添加一个这样的组合框列,就选择新建DataGridViewComboBoxColumn,然后添加到datagridview中去就可以了,这是基本想法。
2、DataGridViewComboBoxColumn的数据绑定
DataGridViewComboBoxColumn有几个关键属性
(1)DataSource:顾名思义,绑定的数据,把需要绑定的表赋值就可以
(2)DataPropertyName:根据msdn说法是设置数据源属性的名称,我理解就是这是从大表里选择数据,用数据源属性名称来标识一下这个是什么属性。可以随意写,也可以不写,应该是起一个提示的作用。
(3)DisplayMember:这是最关键的属性,首先,它必须是数据表的一个字段,其次,它是前台显示出的数据。所以,它就是相当于一个select语句,从DataSource的Table中检索字段名=DisplayMember的所有数据。Select ‘DisplayMember’ from ‘DataSource’(‘’中的表示用相应的实际数据替换),其实理论上DisplayMember+DataSource就可以完成了这个combox嵌入datagridview的功能了。
(4)ValueMember:
Gets or sets a string that specifies the property or column from which to get values that correspond to the selections in the drop-down list.
获取或设置一个字符串,此字符串指定要从其中获取与下拉列表的选项对应的值的属性或列。
这个属性应该是为了和DisplayMember组成一个映射关系,但是根据msdn的说法
In this example, the DisplayMember is set to the same value as ValueMember because no mapping is necessary.
DisplayMember 设置为负责包含用户可查看的文本的属性名称。 在此示例中, DisplayMember 设置相同的值为 ValueMember 因为没有映射是必需的。
虽然这个翻译很费解,但是勉强能懂,就是在不需要映射时,将ValueMember 的值设置的和DisplayMember 一样就好了。
那就写几行代码示意一下:
private void Form2_Load(object sender, EventArgs e)
{
//辅助处理类,不用管
EvaluateHierarchyManage.EvaluateHierarchyManage standard = new EvaluateHierarchyManage.EvaluateHierarchyManage();
//Standard绑定了一张数据库里的表"EvaluateHierarchy"
DataSet Standard= standard.GetAllInfo();
//辅助处理类,不用管
EvaluateDataManage.EvaluateDataManage data = new EvaluateDataManage.EvaluateDataManage();
//data绑定了一张数据库里的表"EvaluateData"
DataSet Data = data.GetAllInfo();
int i = 0;
for (i = 0; i < data.Tables[0].Columns.Count; i++)
{
//添加用户选择栏
DataGridViewComboBoxColumn combox = new DataGridViewComboBoxColumn();
combox.DataPropertyName = "PrimeStandard1";
//必须和数据库字段名保持一致,此字段中的数据为前台显示在datagridview的数据
combox.DisplayMember = "Classification";
//和DisplayMember 保持一致
combox.ValueMember = "PrimeStandard";
//绑定数据
combox.DataSource = data.Tables[0];
//添加到datagridview控件
dataGridView1.Columns.Add(combox);
}
}
然后再谈一个小问题:我的软件设计上要出现这种情况:用户的输入可能是不规范的,我提供给他combox进行选择,同时他也需要输入数据,用户输入的数据是作为原始数据留存,用户选择的数据是作为计算的依据(因为预制的选项对于软件开发的人来讲一定是规范的)
大概就像这样
也写了两行代码来实现,当然也很简单,就是不同的列的组合,也po上来做个记录
private void Form2_Load(object sender, EventArgs e)
{
EvaluateHierarchyManage.EvaluateHierarchyManage standard = new EvaluateHierarchyManage.EvaluateHierarchyManage();
DataSet Standard= standard.GetAllInfo();
EvaluateDataManage.EvaluateDataManage data = new EvaluateDataManage.EvaluateDataManage();
DataSet Data = data.GetAllInfo();
DataBase.DataBase database = new DataBase.DataBase();
List<string> columnsname=new List<string>();
foreach(DataColumn c in Data.Tables[0].Columns)
{
columnsname.Add(c.ColumnName);
}
foreach (string s in columnsname)
{
string sql = "select Classification,ID from EvaluateHierarchy where TwoLevelStandard='" + s+"'";
SqlCommand command = new SqlCommand(sql,database.con);
SqlDataAdapter sda = new SqlDataAdapter(command);
DataSet ds = new DataSet();
sda.Fill(ds);
//添加用户填写栏
if (ds.Tables[0].Rows.Count != 0)
{
DataGridViewTextBoxColumn dgvc = new DataGridViewTextBoxColumn();
dgvc.HeaderText = s + "用户填写";
dataGridView1.Columns.Add(dgvc);
}
//添加用户选择栏
DataGridViewComboBoxColumn combox = new DataGridViewComboBoxColumn();
combox.DataPropertyName = "Classification";
//必须和数据库字段名保持一致,此字段中的数据为前台显示在datagridview的数据
combox.DisplayMember = "Classification";
//必须和DisplayMember字段保持一致
combox.ValueMember = "Classification";
combox.DataSource = ds.Tables[0];
combox.HeaderText = s;
try
{
dataGridView1.Columns.Add(combox);
}
catch(Exception ex)
{
}
}
}
有一个关于这个话题的很好的代码
MSDN关于DataGridViewComboBoxColumn的示例
但是我一时没有调通代码,不过算是很好的提示了。