DataGridView控制元件用法(二):為每行記錄最後加“編輯”-“刪除”按鈕列
1. 在中已經顯示出列表資料,這時我們需要對每行資料記錄進行編輯,需要新增“編輯”、“刪除”、“檢視”這樣的超連結。程式碼如下:
1 |
//為每行資料增加編輯列。 |
2 |
//設定列不能自動作成 |
3 |
UserdataGridView.AutoGenerateColumns =
false ;
|
4 |
//建立一個DataGridViewLinkColumn列
|
5 |
DataGridViewLinkColumn dlink =
new DataGridViewLinkColumn();
|
6 |
dlink.Text = "編輯" ; //新增的這列的顯示文字,即每行最後一列顯示的文字。
|
7 |
dlink.Name = "linkEdit" ;
|
8 |
dlink.HeaderText = "編輯" ; //列的標題
|
9 |
dlink.UseColumnTextForLinkValue =
true ; //上面設定的dlink.Text文字在列中顯示
|
10 |
UserdataGridView.Columns.Add(dlink); //將建立的列新增到UserdataGridView中
|
11 |
12 |
//同上方法為每條記錄建立“刪除”超連結
|
13 |
DataGridViewLinkColumn dlink2 =
new DataGridViewLinkColumn();
|
14 |
dlink2.Text = "刪除" ;
|
15 |
dlink2.Name = "linkDelete" ;
|
16 |
dlink2.HeaderText = "刪除" ;
|
17 |
dlink2.UseColumnTextForLinkValue =
true ;
|
18 |
UserdataGridView.Columns.Add(dlink2);
|
19 |
20 |
//同上方法為每條記錄建立“檢視”超連結
|
21 |
DataGridViewLinkColumn dlink3 =
new DataGridViewLinkColumn();
|
22 |
dlink3.Text = "檢視" ;
|
23 |
dlink3.Name = "linkView" ;
|
24 |
dlink3.HeaderText = "檢視" ;
|
25 |
dlink3.UseColumnTextForLinkValue =
true ;
|
26 |
UserdataGridView.Columns.Add(dlink3); |
執行效果如下:
PS:上述是自己編寫程式碼實現這些按鈕,你也可以在設計器中利用屬性欄來新增(通過直接點選的編輯列,點選“新增”,選擇“未繫結列”,選擇型別為“DataGridViewButtonColumn”)。
同理:單元格顯示按鈕(DataGridViewButtonColumn),新增下拉框(DataGridViewComboBoxColumn),顯示選擇框(DataGridViewCheckBoxColumn) 方法也是這樣。實際上DataGridViewColumn有六種派生類: DataGridViewButtonColumn,DataGridViewCheckBoxColumn,DataGridViewComboBoxColumn,DataGridViewImageColumn
, 和DataGridViewTextBoxColumn,你可以根據自己不同需要選擇不同列的型別,用法一樣,只是類不同而已。
DataGridViewButtonColumn用法如下:
1 |
//設定列不能自動作成 |
2 |
UserdataGridView.AutoGenerateColumns =
false ;
|
3 |
//建立一個DataGridViewButtonColumn按鈕列
|
4 |
DataGridViewButtonColumn dbtEdit =
new DataGridViewButtonColumn();
|
5 |
dbtEdit.Text = "編輯" ; //新增的這列的顯示文字,即每行最後一列顯示的文字。
|
6 |
dbtEdit.Name = "buttonEdit" ;
|
7 |
dbtEdit.HeaderText = "編輯" ; //列的標題
|
8 |
dbtEdit.UseColumnTextForButtonValue =
true ; //上面設定的dlink.Text文字在列中顯示
|
9 |
dbtEdit.Width = 66; |
10 |
UserdataGridView.Columns.Add(dbtEdit); //將建立的列新增到UserdataGridView中
|
11 |
12 |
//建立“刪除”按鈕 |
13 |
DataGridViewButtonColumn dbtDelete =
new DataGridViewButtonColumn();
|
14 |
dbtDelete.Text = "刪除" ;
|
15 |
dbtDelete.Name = "buttonDelete" ;
|
16 |
dbtDelete.HeaderText = "刪除" ;
|
17 |
dbtDelete.UseColumnTextForButtonValue =
true ;
|
18 |
dbtDelete.Width = 66; |
19 |
UserdataGridView.Columns.Add(dbtDelete);
|
20 |
21 |
//建立“檢視”按鈕 |
22 |
DataGridViewButtonColumn dbtView =
new DataGridViewButtonColumn();
|
23 |
dbtView.Text = "檢視" ;
|
24 |
dbtView.Name = "buttonView" ;
|
25 |
dbtView.HeaderText = "檢視" ;
|
26 |
dbtView.UseColumnTextForButtonValue =
true ;
|
27 |
dbtView.Width = 66; |
28 |
UserdataGridView.Columns.Add(dbtView); |
效果如下:
單元格新增下拉框,DataGridViewComboBoxColumn用法如下:
1 |
DataGridViewComboBoxColumn dCombo =
new DataGridViewComboBoxColumn();
|
2 |
dCombo.Items.Add( "管理員" );
|
3 |
dCombo.Items.Add( "會員" );
|
4 |
dCombo.Items.Add( "使用者" );
|
5 |
dCombo.Name = "dCombo" ;
|
6 |
//該列顯示的位置 |
7 |
//dcombo.DisplayIndex = 1;
|
8 |
dCombo.HeaderText = "角色" ;
|
9 |
10 |
//繫結資料庫的值時使用以下屬性 |
11 |
//dCombo.DataSource = ds1 //ds1為從要顯示的資料庫表中查出來的資料集,如DatsSet等。
|
12 |
//dCombo.DataPropertyName = "USER_ID";//繫結的列
|
13 |
14 |
UserdataGridView.Columns.Add(dCombo); |
效果如下:
注意:上圖左邊的下拉框無法展開下面的資料,因為dataGridView的下拉框是在編輯表格可以編輯狀態時才能拉出下面的選項,也就是說需要在dataGridView的ReadOnly屬性為false的情況下,才可點選展開下面的資料,如上右圖。
上述程式碼建立了一個下拉列表,預設顯示的下拉框,選擇時需要點選三次,第一次選中單元格,第二次啟用編輯,第三次開啟下拉框。如果需要一次點選開啟下拉框,可以啟用DataGridView的CellEnter()事件,程式碼如下:
1 |
private
void UserdataGridView_CellEnter( object
sender, DataGridViewCellEventArgs e) |
2 |
{ |
3 |
//實現單擊一次顯示下拉列表框
|
4 |
if
(UserdataGridView.Columns[e.ColumnIndex] is
DataGridViewComboBoxColumn && e.RowIndex != -1)
|
5 |
{
|
6 |
SendKeys.Send( "{F4}" );
|
7 |
}
|
8 |
} |
PS:還可以將下拉框動態繫結資料庫。通過dCombo.DataSource和dcombo.DataPropertyNam來設定該下拉框資料來自的資料來源,和繫結的列,具體用法略。
單元格新增複選框和圖片控制元件,DataGridViewCheckBoxColumn,DataGridViewImageColumn用法如下:
1 |
//DataGridView顯示覆選框 |
2 |
DataGridViewCheckBoxColumn checkBox =
new DataGridViewCheckBoxColumn();
|
3 |
checkBox.HeaderText = "選擇框" ;
|
4 |
checkBox.Name = "checkbox" ;
|
5 |
checkBox.AutoSizeMode = |
6 |
DataGridViewAutoSizeColumnMode.DisplayedCells;
|
7 |
checkBox.FlatStyle = FlatStyle.Standard;
|
8 |
//顯示選擇框的三種狀態 |
9 |
checkBox.ThreeState = true ;
|
10 |
UserdataGridView.Columns.Add(checkBox);
|
11 |
12 |
//DataGridView顯示影象 |
13 |
DataGridViewImageColumn dgvI =
new DataGridViewImageColumn();
|
14 |
dgvI.Name = "Image" ;
|
15 |
dgvI.ValuesAreIcons = false ;
|
16 |
dgvI.Image = new
Bitmap( "F://ashin.jpg" );
|
17 |
dgvI.ImageLayout = DataGridViewImageCellLayout.Zoom;
|
18 |
dgvI.Description = "測試的圖片" ;
|
19 |
UserdataGridView.Columns.Add(dgvI); |
效果如下:
2. 按鈕觸發的事件。添加了這些按鈕是為了點選跳到不同的程式段執行不同的功能,攔截滑鼠點選觸發的事件函式如下:
1 |
//在表格上單擊觸發的事件,不同的按鈕或超連結或圖片下拉框等等都在這裡判斷。
|
2 |
private
void UserdataGridView_CellContentClick( object
sender, DataGridViewCellEventArgs e) |
3 |
{ |
4 |
if
(UserdataGridView.Columns[e.ColumnIndex].Name ==
"buttonEdit" )
|
5 |
{
|
6 |
MessageBox.Show( "觸發了編輯按鈕" );
|
7 |
}
|
8 |
else
if (UserdataGridView.Columns[e.ColumnIndex].Name ==
"buttonDelete" )
|
9 |
{
|
10 |
MessageBox.Show( "觸發了刪除按鈕" );
|
11 |
}
|
12 |
else
if (UserdataGridView.Columns[e.ColumnIndex].Name ==
"buttonView" )
|
13 |
{
|
14 |
MessageBox.Show( "觸發了檢視按鈕" );
|
15 |
}
|
16 |
} |
3. DataGridView中合併列。上述我們新增的3個按鈕在3個列中,而我們希望這3個列能有一個共同的表頭可以叫做“編輯”或“操作”。但在WinForm中我們常用的DataGridView控制元件,不支援在一列中顯示多個按鈕。怎麼辦?網上對DataGridView控制元件的列或行的合併有很多博文,大致思想有2種,一種是設法讓其一列可以顯示多個按鈕,另一種是每列顯示一個按鈕(如本文上面的做法),然後將這3列合併,合併的時候是利用DataGridView的CellPainting事件對錶頭進行重繪,網友們說該方法存在頁面往下拉動時表格繪製偏差或繪製延遲不重新整理等問題,似乎後面這種方法用的多些。總之無論哪種方法實現起來都貌似比較繁瑣,時間有限,我只是練練手(本身就是新手),弄個小程式而已,不想花太多時間研究這個小細節,等以後有空,再回來仔細研究研究。下面給個合併列的例子,有個朋友是這樣實現二維表頭的,程式碼如下:
1 |
int
top = 0; |
2 |
int
left = 0; |
3 |
int
height = 0; |
4 |
int
width1 = 0; |
5 |
private
void dataGridView1_CellPainting( object
sender, DataGridViewCellPaintingEventArgs e) |
6 |
{ |
7 |
#region 重繪datagridview表頭
|
8 |
DataGridView dgv = (DataGridView)(sender);
|
9 |
if
(e.RowIndex == -1 && (e.ColumnIndex == 3 || e.ColumnIndex == 4))
|
10 |
{
|
11 |
//e.CellStyle.Font = new Font(dataGridView1.DefaultCellStyle.Font, FontStyle.Bold);
|
12 |
//e.CellStyle.WrapMode = DataGridViewTriState.True;
|
13 |
if
(e.ColumnIndex == 3) |
14 |
{
|
15 |
top = e.CellBounds.Top;
|
16 |
left = e.CellBounds.Left;
|
17 |
height = e.CellBounds.Height;
|
18 |
width1 = e.CellBounds.Width;
|
19 |
}
|
20 |
21 |
int
width2 = this .dataGridView1.Columns[4].Width;
|
22 |
23 |
Rectangle rect =
new Rectangle(left, top, width1 + width2, e.CellBounds.Height);
|
24 |
using
(Brush backColorBrush = new
SolidBrush(e.CellStyle.BackColor)) |
25 |
{
|
26 |
//抹去原來的cell背景
|
27 |
e.Graphics.FillRectangle(backColorBrush, rect);
|
28 |
}
|
29 |
30 |
using
(Pen gridLinePen = new
Pen(dgv.GridColor)) |
31 |
{
|
32 |
e.Graphics.DrawLine(gridLinePen, left, top, left + width1 + width2, top);
|
33 |
e.Graphics.DrawLine(gridLinePen, left, top + height / 2, left + width1 + width2, top + height / 2);
|
34 |
e.Graphics.DrawLine(gridLinePen, left + width1, top + height / 2, left + width1, top + height);
|
35 |
36 |
//計算繪製字串的位置
|
37 |
string
columnValue = Year; |
38 |
SizeF sf = e.Graphics.MeasureString(columnValue, e.CellStyle.Font);
|
39 |
float
lstr = (width1 + width2 - sf.Width) / 2; |
40 |
float
rstr = (height / 2 - sf.Height) / 2; |
41 |
//畫出文字框
|
42 |
if
(columnValue != "" )
|
43 |
{
|
44 |
e.Graphics.DrawString(columnValue, e.CellStyle.Font,
new SolidBrush(e.CellStyle.ForeColor),
|
45 |
left + lstr,
|
46 |
top + rstr,
|
47 |
StringFormat.GenericDefault);
|
48 |
}
|
49 |
50 |
//計算繪製字串的位置
|
51 |
columnValue =
"局網臺資產額" ;
|
52 |
sf = e.Graphics.MeasureString(columnValue, e.CellStyle.Font);
|
53 |
lstr = (width1 - sf.Width) / 2;
|
54 |
rstr = (height / 2 - sf.Height) / 2;
|
55 |
//畫出文字框
|
56 |
if
(columnValue != "" )
|
57 |
{
|
58 |
e.Graphics.DrawString(columnValue, e.CellStyle.Font,
new SolidBrush(e.CellStyle.ForeColor),
|
59 |
left + lstr,
|
60 |
top + height / 2 + rstr,
|
61 |
StringFormat.GenericDefault);
|
62 |
}
|
63 |
64 |
//計算繪製字串的位置
|
65 |
columnValue =
"網路資產額" ;
|
66 |
sf = e.Graphics.MeasureString(columnValue, e.CellStyle.Font);
|
67 |
lstr = (width2 - sf.Width) / 2;
|
68 |
rstr = (height / 2 - sf.Height) / 2;
|
69 |
//畫出文字框
|
70 |
if
(columnValue != "" )
|
71 |
{
|
72 |
e.Graphics.DrawString(columnValue, e.CellStyle.Font,
new SolidBrush(e.CellStyle.ForeColor),
|
73 |
left + width1 + lstr,
|
74 |
top + height / 2 + rstr,
|
75 |
StringFormat.GenericDefault);
|
76 |
}
|
77 |
}
|
78 |
e.Handled =
true ;
|
79 |
}
|
80 |
#endregion
|
81 |
} |
不過:雖然沒有仔細研究列的合併,我暫時還是找了個方法一定程度上替代了合併問題。因為我需要的是合併“刪除”、“編輯”和“檢視”這三列,本想就不顯示錶頭好了,反正是操作列,不顯示錶頭不注意也看不出什麼來。巧合,我發現愛英思躺一個月以前釋出了一篇部落格專門介紹EasyCode生成器生成的修改、刪除資訊列表介面,用的是EasyCode 2.0版本,生成的頁面第一感覺就是非常清新,真是眼前一亮,原來EasyCode程式碼生成器這麼強大!!更誘人的是正有我想要的類似的合併列的功能,為什麼說類似呢,因為樣子是一樣,但他是將1列(一個單元格)裡面放置2個按鈕,而不是常見的那種一列放一個按鈕然後合併單元格的表頭。下面就是愛英思躺團隊用EasyCode 2.0.50727.4963版本生成的WinForm中DataGridView控制元件的自定義按鈕列的外觀,請看:
關於如何設計WinForm中DataGridView控制元件的自定義按鈕列,詳細可參考該部落格:
我並沒有用生成的所有程式碼,而是隻拿出了其中的DataGridViewActionButtonColumn.cs類當控制元件來用的(該類是作者們繼承DataGridViewColumn類,自己定製的一個控制元件而已!正如我們前面提到的DataGridViewColumn有六種派生類: DataGridViewButtonColumn,DataGridViewCheckBoxColumn…一樣!) 我的用法,詳見下一篇:DataGridView控制元件用法(三)。