http://www.cnblogs.com/redjackwong/archive/2005/10/14/254840.html
今天群上一个MM问了一个问题,问题描述如下:
如何在DataGrid中添加一列CheckedListBox用作选取该列和复选多列。
当然既然是MM问的,而且我也对此很感兴趣,所以就接下来了。
此时我并不知道DataGrid的表样式映射功能,所以试了下将CheckedListBox和CheckBox直接放在DataGrid的后面-------结果,还真难看。后来想了想,既然这是MicroSoft的东西,这么常用的功能,应该在DataGrid中有集成。于是在属性栏中找,发现TableStyles(表样式)属性,凭直觉就感觉到这个是关键。点Collection子菜单,添加一个新表样式,在其属性中发现GridColumnStyles(Grid列样式),啊哈,就是它了。
当然使用表样式映射可以直接在属性栏中可视化完成,不过这样不够动态,以下解决过程采用代码编辑方式完成,便于动态改变和深入理解。
1、本例数据源采用xml格式,简单方便
<Points>
<Point>
<X>0.00</X>
<Y>0.00</Y>
</Point>
<Point>
<X>78.50</X>
<Y>70.71</Y>
</Point>
<Point>
<X>157.10</X>
<Y>100.00</Y>
</Point>
<Point>
<X>235.60</X>
<Y>70.71</Y>
</Point>
<Point>
<X>314.10</X>
<Y>0.00</Y>
</Point>
<Point>
<X>392.60</X>
<Y>-70.71</Y>
</Point>
</Points>
2、首先新建一个DataSet,并在构造函数中加载数据源
{
InitializeComponent();
ds.ReadXml("Points.xml");
3、添加一新列,作为显示为CheckBox的列,并将数据类型定义为bool,初始化为false。并绑定DataSet到dataGrid1
for(int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
ds.Tables[0].Rows[i]["newc"]=false; //初始为未选中
}
dataGrid1.DataSource = ds.Tables[0].DefaultView;
4、新建一个表样式DataGridTableStyle,映射到DataSet的第一个表
ts1.MappingName = ds.Tables[0].TableName; //映射到Tables[0]
5、新建与列数一样多的DataGridTextBoxColumn,映射到表原有的列(e.g.本例中的X和Y),表示以常规文本方式显示数据,并将其按顺序添加到表样式中
t1.HeaderText = "X"; //显示标题为X
t1.MappingName = "X"; //映射到X列
ts1.GridColumnStyles.Add(t1); //添加到表样式中
DataGridTextBoxColumn t2 = new DataGridTextBoxColumn();
t2.HeaderText = "Y";
t2.MappingName = "Y";
ts1.GridColumnStyles.Add(t2);
6、新建一个DataGridBoolColumn,映射到新添加的列,表示以CheckBox样式显示bool型数据,并将其添加到表样式中
b1.HeaderText = "My New Column"; //显示标题
b1.MappingName = "newc"; //映射列
b1.NullText="false"; //空值为false
b1.TrueValue=true; //选中值为true
b1.FalseValue=false; //未选中值为false
b1.ReadOnly=false; //取消只读
ts1.GridColumnStyles.Add(b1); //添加到表样式中
7、最后将DataGridTableStyle添加到DataGrid中
8、运行即可看到结果。如要对选中行进行处理,可以用一循环判断newc值,为true时即为选中该行,然后进行操作。
9、附全代码,包括选中行删除功能
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace Test
{
public class Form1 : System.Windows.Forms.Form
{
private DataSet ds = new DataSet();
private System.Windows.Forms.DataGrid dataGrid1;
private System.Windows.Forms.Button button1;
private System.ComponentModel.Container components = null;
public Form1()
{
InitializeComponent();
ds.ReadXml("Points.xml");
ds.Tables[0].Columns.Add("newc",false.GetType()).DefaultValue=false;
for(int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
ds.Tables[0].Rows[i]["newc"]=false;
}
dataGrid1.DataSource = ds.Tables[0].DefaultView;
DataGridTableStyle ts1 = new DataGridTableStyle();
ts1.MappingName = ds.Tables[0].TableName;
DataGridTextBoxColumn t1 = new DataGridTextBoxColumn();
t1.HeaderText = "X";
t1.MappingName = "X";
ts1.GridColumnStyles.Add(t1);
DataGridTextBoxColumn t2 = new DataGridTextBoxColumn();
t2.HeaderText = "Y";
t2.MappingName = "Y";
ts1.GridColumnStyles.Add(t2);
DataGridBoolColumn b1 = new DataGridBoolColumn();
b1.HeaderText = "My New Column";
b1.MappingName = "newc";
b1.NullText="false";
b1.TrueValue=true;
b1.FalseValue=false;
b1.ReadOnly=false;
ts1.GridColumnStyles.Add(b1);
dataGrid1.TableStyles.Add(ts1);
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
private void InitializeComponent()
{
this.dataGrid1 = new System.Windows.Forms.DataGrid();
this.button1 = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).BeginInit();
this.SuspendLayout();
// dataGrid1
this.dataGrid1.DataMember = "";
this.dataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText;
this.dataGrid1.Location = new System.Drawing.Point(8, 8);
this.dataGrid1.Name = "dataGrid1";
this.dataGrid1.Size = new System.Drawing.Size(280, 264);
this.dataGrid1.TabIndex = 0;
// button1
this.button1.Location = new System.Drawing.Point(296, 248);
this.button1.Name = "button1";
this.button1.TabIndex = 1;
this.button1.Text = "button1";
this.button1.Click += new System.EventHandler(this.button1_Click);
// Form1
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(376, 277);
this.Controls.Add(this.button1);
this.Controls.Add(this.dataGrid1);
this.Name = "Form1";
this.Text = "Form1";
((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).EndInit();
this.ResumeLayout(false);
}
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void button1_Click(object sender, System.EventArgs e)
{
for(int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
if ((bool)(ds.Tables[0].Rows[i]["newc"])==true)
{
ds.Tables[0].Rows[i].Delete();
}
}
}
}
}
更好的解决方法是在数据源中本来就留有一列为bool型数据,这样就避免了程序中添加列,只需要直接映射就可以了。
如果有更好的办法请联系我,我也觉得这个方法挺复杂的。