也不知道是否该应用这个控件,不过也想不出该用其他什么控件,关键是俺比较菜没什么经验。
要求是这样的,用户一次添加一个任务,这个任务有三个选项,其中两个选项是用户动态输入的名称(就象图中bb和dd两列),另一个选项则是一堆数据(就象qq那列),我现在要把每个任务罗列出来,不能用treeview,不能用tabcontrol,不能用xml,最好象个表格一样清晰明朗(疯了!)每个任务对应两个按钮,一个是Run,为了跑任务,一个是Remove,为了移除任务。

当然最开始选择DataGridView就是为了满足那个“象表格一样清晰明朗”的奇怪需求,一行对应一个任务,其次貌似DataGridView控件在.net 2.0中加入了新的特征如DataGridViewButtonColumn啊,DataGridViewComboBoxColumn之类的东东。研究了一天才发现这两个东东根本派不上用场,首先DataGridViewButtonColumn中的Button跟真的Button根本没得比,既不能添加Button的Text也不好添加Click事件(应该是有方法的但还是很别扭而且也没研究);其次是DataGridViewComboBoxColumn,不仅外观上不能和真正的ComboBox相提并论,而且当你选择了其中的任一item,DataGridView就会新增一行,这跟我们的需求是完全不符合的,毕竟一个选项是不能代表一个任务的。
从网上查了很多资料,呵呵,看到一篇说可以画个控件上去,觉得很有意思。其实我就是这么做的。
(1)首先初始化DataGridView控件。
private
void
Form1_Load(
object
sender, EventArgs e)
{
DataGridViewCellStyle columnHeaderStyle
=
new
DataGridViewCellStyle();
columnHeaderStyle.BackColor
=
Color.Beige;
columnHeaderStyle.Font
=
new
Font(
"
Verdana
"
,
10
, FontStyle.Bold);
dataGridView1.ColumnHeadersDefaultCellStyle
=
columnHeaderStyle;
this
.dataGridView1.Columns.Add(
"
1
"
,
"
bb
"
);
this
.dataGridView1.Columns.Add(
"
2
"
,
"
qq
"
);
this
.dataGridView1.Columns.Add(
"
3
"
,
"
dd
"
);
this
.dataGridView1.Columns.Add(
"
4
"
,
"
aa
"
);
}
(2)单击按钮添加一行,包括单元格和单元格的值,看似内嵌在单元格中的按钮和下拉列表
private
void
button4_Click(
object
sender, EventArgs e)
{
DataGridViewRow dr
=
new
DataGridViewRow();
foreach
(DataGridViewColumn c
in
this
.dataGridView1.Columns)
{
dr.Cells.Add(c.CellTemplate.Clone()
as
DataGridViewCell);
//
给行添加单元格
}
dr.Cells[
0
].Value
=
"
1111
"
;
dr.Cells[
2
].Value
=
"
3333
"
;
this
.dataGridView1.Rows.Add(dr);
int
index
=
this
.dataGridView1.Rows.Count
-
2
;
ComboBox com
=
new
ComboBox();
com.Name
=
"
Containers
"
+
index.ToString(); ;
com.DropDownStyle
=
System.Windows.Forms.ComboBoxStyle.DropDownList;
com.FlatStyle
=
System.Windows.Forms.FlatStyle.Flat;
com.Items.AddRange(
new
object
[] {
"
1
"
,
"
2
"
,
"
3
"
,
"
4
"
});
com.SelectedIndex
=
0
;
this
.dataGridView1.Controls.Add(com);
this
.dataGridView1.Columns[
1
].Width
=
com.Width;
com.Location
=
new
System.Drawing.Point(((
this
.dataGridView1.GetCellDisplayRectangle(
1
, index,
true
).Right)
-
(com.Width)),
this
.dataGridView1.GetCellDisplayRectangle(
1
, index,
true
).Y);
Button btn1
=
new
Button();
btn1.Name
=
"
btnRun
"
+
index.ToString(); ;
btn1.Text
=
"
Run
"
;
btn1.Click
+=
new
EventHandler(btn1_Click);
Button btn2
=
new
Button();
btn2.Name
=
"
btnRemove
"
+
index.ToString();
btn2.Text
=
"
Remove
"
;
btn2.Click
+=
new
EventHandler(btn2_Click);
this
.dataGridView1.Controls.Add(btn1);
this
.dataGridView1.Controls.Add(btn2);
this
.dataGridView1.Columns[
3
].Width
=
btn1.Width
+
btn2.Width
+
6
;
btn1.Location
=
new
System.Drawing.Point(((
this
.dataGridView1.GetCellDisplayRectangle(
3
, index,
true
).Left)),
this
.dataGridView1.GetCellDisplayRectangle(
3
, index,
true
).Y);
btn2.Location
=
new
System.Drawing.Point(((
this
.dataGridView1.GetCellDisplayRectangle(
3
, index,
true
).Right
-
1
)
-
(btn2.Width)),
this
.dataGridView1.GetCellDisplayRectangle(
3
, index,
true
).Y);
}
(3)为(2)中生成的Run按钮和Remove按钮添加单击事件处理程序
public
void
btn1_Click(
object
sender, EventArgs e)
{
this
.richTextBox1.Text
=
""
;
Button btn
=
(Button)(sender);
//
这个btn的name是btnRun打头的
string
suffix
=
btn.Name.ToString().Substring(
6
);
//
后边那个号,相当于index的string
Control c
=
findControlByName(suffix);
if
(c
!=
null
)
{
ComboBox com
=
(ComboBox)(c);
//
Control ctl1 = this.dataGridView1.Controls["Containers" + i.ToString()];
//
ComboBox com = (ComboBox)ctl1; 其实这样写更简单点
for
(
int
i
=
0
; i
<
com.Items.Count; i
++
)
{
this
.richTextBox1.Text
+=
com.Items[i].ToString()
+
"
\n
"
;
}
}
}
public
void
btn2_Click(
object
sender, EventArgs e)
{
int
RowCount
=
this
.dataGridView1.Rows.Count;
Button btn
=
(Button)(sender);
//
这个btn的name是btnRemove打头的
string
suffix
=
btn.Name.ToString().Substring(
9
);
//
后边那个号,相当于index的string
this
.dataGridView1.Controls.RemoveByKey(btn.Name);
this
.dataGridView1.Controls.RemoveByKey(
"
btnRun
"
+
suffix);
this
.dataGridView1.Controls.RemoveByKey(
"
Containers
"
+
suffix);
int
index
=
Convert.ToInt32(suffix);
this
.dataGridView1.Rows.RemoveAt(index);
if
(index
<
RowCount
-
2
)
{
for
(
int
i
=
index
+
1
; i
<
RowCount
-
1
; i
++
)
{
Control ctl1
=
this
.dataGridView1.Controls[
"
Containers
"
+
i.ToString()];
Control ctl2
=
this
.dataGridView1.Controls[
"
btnRun
"
+
i.ToString()];
Control ctl3
=
this
.dataGridView1.Controls[
"
btnRemove
"
+
i.ToString()];
ComboBox com
=
(ComboBox)ctl1;
Button btnRun
=
(Button)ctl2;
Button btnRemove
=
(Button)ctl3;
//
上移一格,单元格Height位4,Button的Height为23
com.Location
=
new
System.Drawing.Point(com.Location.X, com.Location.Y
-
23
);
btnRun.Location
=
new
System.Drawing.Point(btnRun.Location.X, btnRun.Location.Y
-
23
);
btnRemove.Location
=
new
System.Drawing.Point(btnRemove.Location.X, btnRemove.Location.Y
-
23
);
//
改名字的后缀
int
j
=
i
-
1
;
com.Name
=
"
Containers
"
+
j.ToString();
btnRun.Name
=
"
btnRun
"
+
j.ToString();
btnRemove.Name
=
"
btnRemove
"
+
j.ToString();
}
}
}
(4)btn1_Click处理中用到的函数findControlByName()
public
Control findControlByName(
string
suffix)
{
foreach
(System.Windows.Forms.Control c
in
this
.dataGridView1.Controls)
{
if
(c.Name
==
"
Containers
"
+
suffix)
return
c;
}
return
null
;
}