< 他們有差別嗎?>
一、需求
爲甚有這種想法呢,那是來自需求的壓迫,可憐我們這些苦逼的程序猿及攻城獅們只能徹夜難眠、苦思冥想、幾十億個腦細胞兄弟們前赴後繼最終才能取得芝麻點大的勝利,好吧我們來看需求。
1. 現在要一個表格,表格的第一列是一個選中操作的複選框,要求能再複選框選中時,也對此行進行行選。
二、分析設計
First,讓我們來看下,GridView中本身帶了哪些我們能用的方法:
a. 自身帶有checkbox列,我們也自定義了我們的擴展checkbox列。
b. 表格本身具有行選屬性。
c. 表格本身帶有多行選擇屬性。
好吧到然後了,通過利用這些已有的屬性我們簡單實現之,在checkbox的選中事件中進行行選操作。然後就實現啦。。。
Wait,這樣真的就這麼簡單的實現了,讓我們仔細想想是不是哪裏不對勁啊?
Yeah,問題又來了:
1) 表格的列是在用的時候才設計checkbox列的,那麼怎樣才能讓這些功能在DataGridView中實現呢?
2) 我們知道checkbox不一定只是爲了選中某一行,它還是一個狀態的控件,比如他要代表是否,我們不能同意而論啊?
Ok,來吧,讓我們重新的整理一下:首先我們採用綁定的方式來設置標誌複選框,即指定多個複選框的其中一個爲標誌行選的複選框。其次,在CellPainting事件中選中該標誌複選框爲選中的行或者設置行單元格顏色等。然後就沒有然後了。。。
三、實現
首先,設置一個標誌列名,如果此屬性設置爲checkbox的列名,則表示該checkbox列是標誌列。
1: private string m_FlagColumnName = string.Empty;2: [Category("ut"), Browsable(true), Description("選中標誌選中列的一項"), Localizable(true)]3: [DefaultValue(null), Editor(typeof(DataGridViewFlagRowEditor), typeof(System.Drawing.Design.UITypeEditor))]4: public string FlagColumnName5: {
6: get
7: {
8: return m_FlagColumnName;9: }
10: set
11: {
12: m_FlagColumnName = value;13: if (!string.IsNullOrEmpty(m_FlagColumnName))14: base.SelectionMode = DataGridViewSelectionMode.FullRowSelect;15: }
16: }
在CellPainting裏處理吧:
1: DataGridViewCheckBoxCellEx paintCell;
2: protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)3: {
4: if (e.ColumnIndex < 0 || e.RowIndex < 0) return;5: if (!this.Columns.Contains(FlagColumnName)) return;6: paintCell = this.Rows[e.RowIndex].Cells[FlagColumnName] as DataGridViewCheckBoxCellEx;7: if (paintCell != null && paintCell.Checked)8: {
9: //e.CellStyle.BackColor = e.CellStyle.SelectionBackColor;10: this.Rows[e.RowIndex].Selected = true;11: }
12:
13: base.OnCellPainting(e);14: }
其實,最重點的在哪裏?我們如何將FlagColumnName設置與標誌checkbox的名字一致呢?手動?不至於吧,所以這裏用到了Editor
1: namespace DataGridViewEx.DataGridViewExs.EditorEx2: {
3: /// <summary>4: ///DataGridViewEx中的RowFlag標識設計器5: /// </summary>6: public class DataGridViewFlagRowEditor : UITypeEditor7: {
8: const string NullValue = "(None)";9: private IWindowsFormsEditorService m_editorService = null;10: public DataGridViewFlagRowEditor()11: : base()12: {
13: }
14:
15: public override object EditValue(System.ComponentModel.ITypeDescriptorContext context,16: IServiceProvider provider, object value)17: {
18: if (context != null && context.Instance != null && provider != null)19: {
20: m_editorService = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;21: DataGridViewCheckBoxColumnEx column = null;22: List<string> columnNameList = new List<string>();23:
24: foreach (IComponent c in context.Container.Components)25: {
26: if (c is DataGridViewCheckBoxColumnEx)27: {
28: column = (DataGridViewCheckBoxColumnEx)c;
29: columnNameList.Add(column.Name);
30: }
31: }
32: if (columnNameList.Count > 0 && m_editorService != null)33: {
34: int i = 0;35: string selectValue = (string)value;36: ListBox listBox = new ListBox();37: listBox.SelectedIndexChanged += new EventHandler(listBox_SelectedIndexChanged);38: listBox.Items.Add(NullValue);
39: foreach (string name in columnNameList)40: {
41: i = listBox.Items.Add(name);
42: if (name == selectValue)43: listBox.SelectedIndex = i;
44: }
45: m_editorService.DropDownControl(listBox);
46: if (listBox.SelectedItem != null)47: {
48: if (listBox.SelectedItem.ToString() == NullValue)49: return string.Empty;50: return listBox.SelectedItem;51: }
52: }
53: }
54: return value;55: }
56:
57: private void listBox_SelectedIndexChanged(object sender, EventArgs e)58: {
59: if (m_editorService != null)60: m_editorService.CloseDropDown();
61: }
62:
63: /// <summary>64: /// Gets the editor style used by the EditValue method.65: /// </summary>66: /// <param name="context">An ITypeDescriptorContext that can be used to gain additional context information.</param>67: /// <returns>A UITypeEditorEditStyle value that indicates the style of editor used by EditValue. If the UITypeEditor does not support this method, then GetEditStyle will return None</returns>68: public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)69: {
70: if (context != null && context.Instance != null)71: {
72: return UITypeEditorEditStyle.DropDown;73: }
74: return base.GetEditStyle(context);75: }
76: }
77: }
這裏的Editor是Winform中自定義控件的一個很好的功能,即UI設計器的擴展。這裏通過Editor使得我們的FlagColumnName通過設計器中尋找到可選的所有的DataGridViewCheckboxColumnEx供用戶選擇:
四、源碼及演示程序下載。
演示程序: FlagCheckboxColumn.rar
開源項目:http://sourceforge.net/p/datagridviewex/code-0/3/tree/trunk/DataGridViewEx/
出處:http://gxjiang.cnblogs.com/
文章版權歸本人所有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。