Winform系列——好看的DataGridView摺疊控件

      來園子幾年了,第一次寫博客。之前看到別人的博客就在想:這些人怎麼能有這麼多時間整理這麼多知識,難道他們不用工做、不用寫代碼、不用交付測試?隨着工做閱歷的增長,發現其實並非時間的問題,關鍵一個字:懶。其實寫博客的好處你們夥都心知肚明。呵呵,第一次寫就這麼多廢話,看樣子真是年紀大了。app

  其實本身以前的5年也一直是作BS的系統,如今剛換的一家公司須要作一個CS的產品。屌了,本身以前一點經驗都沒有呢,沒辦法,既來之則安之,學唄。因而乎各類百度、各類視頻,各類資料。系統其中一個需求就是須要表格摺疊顯示,這若是在BS裏面那太簡單了,JqGrid默認都自帶,但是DataGridview不支持摺疊啊,咋辦。本身封裝唄,因而乎又是各類百度,這種源碼學習。最後借鑑源碼封了這麼一個東西,發出來分享下,也能讓本身加深印象。首先很少說,上圖:ide

 

 

大概的效果就是這樣。上代碼。函數

一、首先重寫DataGridview,代碼以下:學習

  1 public class MasterControl : DataGridView
  2     {
  3         #region 字段
  4         private List<int> rowCurrent = new List<int>();
  5         internal static int rowDefaultHeight = 22;
  6         internal static int rowExpandedHeight = 300;
  7         internal static int rowDefaultDivider = 0;
  8         internal static int rowExpandedDivider = 300 - 22;
  9         internal static int rowDividerMargin = 5;
 10         internal static bool collapseRow;
 11      //detailControl變量做爲一個容器用來保存子表格
 12         public detailControl childView = new detailControl() { Visible = false }; // VBConversions Note: Initial value cannot be assigned here since it is non-static.  Assignment has been moved to the class constructors.
 13         //
 14         internal System.Windows.Forms.ImageList RowHeaderIconList;
 15         private System.ComponentModel.Container components = null;
 16         //
 17         DataSet _cDataset;
 18         string _foreignKey;
 19         string _primaryKey;
 20         string _filterFormat;
 21         private controlType EControlType;
 22         public int ExpandRowIndex = 0;
 23         
 24 
 25         #endregion
 26 
 27         #region 構造函數
 28         /// <summary>
 29         /// 經過傳遞過來的枚舉判斷是兩級仍是三級展開,表的對應關係經過Relations來讀取
 30         /// 因此調用此構造函數的時候必需要講Relations設置正確,才能正確顯示層級關係。
 31         ///  oDataSet.Relations.Add("1", oDataSet.Tables["T1"].Columns["Menu_ID"], oDataSet.Tables["T2"].Columns["Menu_ID"]);
 32         ///  oDataSet.Relations.Add("2", oDataSet.Tables["T2"].Columns["Menu_Name2"], oDataSet.Tables["T3"].Columns["Menu_Name2"]);
 33         ///  這兩次Add的順序不能顛倒,必須先添加1、二級的表關聯,再添加2、三級的表關聯
 34         /// </summary>
 35         /// <param name="cDataset">數據源DataSet,裏面還有各個表的對應關係</param>
 36         /// <param name="eControlType">枚舉類型</param>
 37         public MasterControl(DataSet cDataset, controlType eControlType)
 38         {
 39             SetMasterControl(cDataset, eControlType);   
 40         }
 41 
 42         /// <summary>
 43         /// 第二種使用方法
 44         /// </summary>
 45         /// <param name="lstData1">摺疊控件第一層的集合</param>
 46         /// <param name="lstData2">摺疊控件第二層的集合</param>
 47         /// <param name="lstData3">摺疊控件第三層的集合</param>
 48         /// <param name="dicRelateKey1">第一二層之間對應主外鍵</param>
 49         /// <param name="dicRelateKey2">第二三層之間對應主外鍵</param>
 50         /// <param name="eControlType">枚舉類型</param>
 51         public MasterControl(object lstData1, object lstData2, 
 52                              object lstData3, Dictionary<string, string> dicRelateKey1, 
 53                              Dictionary<string ,string>dicRelateKey2, controlType eControlType)
 54         {
 55             var oDataSet = new DataSet();
 56             try
 57             {
 58                 var oTable1 = new DataTable();
 59                 oTable1 = Fill(lstData1);
 60                 oTable1.TableName = "T1";
 61 
 62                 var oTable2 = Fill(lstData2);
 63                 oTable2.TableName = "T2";
 64 
 65                 if (lstData3 == null || dicRelateKey2 == null || dicRelateKey2.Keys.Count <= 0)
 66                 {
 67                     oDataSet.Tables.AddRange(new DataTable[] { oTable1, oTable2 });
 68                     oDataSet.Relations.Add("1", oDataSet.Tables["T1"].Columns[dicRelateKey1.Keys.FirstOrDefault()], oDataSet.Tables["T2"].Columns[dicRelateKey1.Values.FirstOrDefault()]);
 69                 }
 70                 else
 71                 {
 72                     var oTable3 = Fill(lstData3);
 73                     oTable3.TableName = "T3";
 74 
 75                     oDataSet.Tables.AddRange(new DataTable[] { oTable1, oTable2, oTable3 });
 76                     //這是對應關係的時候主鍵必須惟一
 77                     oDataSet.Relations.Add("1", oDataSet.Tables["T1"].Columns[dicRelateKey1.Keys.FirstOrDefault()], oDataSet.Tables["T2"].Columns[dicRelateKey1.Values.FirstOrDefault()]);
 78                     oDataSet.Relations.Add("2", oDataSet.Tables["T2"].Columns[dicRelateKey2.Keys.FirstOrDefault()], oDataSet.Tables["T3"].Columns[dicRelateKey2.Values.FirstOrDefault()]);
 79                 }
 80             }
 81             catch
 82             {
 83                 oDataSet = new DataSet();
 84             }
 85             SetMasterControl(oDataSet, eControlType);
 86         }
 87 
 88         /// <summary>
 89         /// 控件初始化
 90         /// </summary>
 91         private void InitializeComponent()
 92         {
 93             this.components = new System.ComponentModel.Container();
 94             base.RowHeaderMouseClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(MasterControl_RowHeaderMouseClick);
 95             base.RowPostPaint += new System.Windows.Forms.DataGridViewRowPostPaintEventHandler(MasterControl_RowPostPaint);
 96             base.Scroll += new System.Windows.Forms.ScrollEventHandler(MasterControl_Scroll);
 97             base.SelectionChanged += new System.EventHandler(MasterControl_SelectionChanged);
 98             System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MasterControl));
 99             this.RowHeaderIconList = new System.Windows.Forms.ImageList(this.components);
100             ((System.ComponentModel.ISupportInitialize)this).BeginInit();
101             this.SuspendLayout();
102             //
103             //RowHeaderIconList
104             //
105             this.RowHeaderIconList.ImageStream = (System.Windows.Forms.ImageListStreamer)(resources.GetObject("RowHeaderIconList.ImageStream"));
106             this.RowHeaderIconList.TransparentColor = System.Drawing.Color.Transparent;
107             this.RowHeaderIconList.Images.SetKeyName(0, "expand.png");
108             this.RowHeaderIconList.Images.SetKeyName(1, "collapse.png");
109             //
110             //MasterControl
111             //
112             ((System.ComponentModel.ISupportInitialize)this).EndInit();
113             this.ResumeLayout(false);
114 
115         }
116         #endregion
117 
118         #region 數據綁定
119         /// <summary>
120         /// 設置表之間的主外鍵關聯
121         /// </summary>
122         /// <param name="tableName">DataTable的表名稱</param>
123         /// <param name="foreignKey">外鍵</param>
124         public void setParentSource(string tableName, string primarykey, string foreignKey)
125         {
126             this.DataSource = new DataView(_cDataset.Tables[tableName]);
127             cModule.setGridRowHeader(this);
128             _foreignKey = foreignKey;
129             _primaryKey = primarykey;
130             if (_cDataset.Tables[tableName].Columns[primarykey].GetType().ToString() == typeof(int).ToString()
131                 || _cDataset.Tables[tableName].Columns[primarykey].GetType().ToString() == typeof(double).ToString()
132                 || _cDataset.Tables[tableName].Columns[primarykey].GetType().ToString() == typeof(decimal).ToString())
133             {
134                 _filterFormat = foreignKey + "={0}";
135             }
136             else
137             {
138                 _filterFormat = foreignKey + "=\'{0}\'";
139             }
140         }
141         #endregion
142 
143         #region 事件
144         //控件的行頭點擊事件
145         private void MasterControl_RowHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
146         {
147             try
148             {
149                 Rectangle rect = new Rectangle(System.Convert.ToInt32((double)(rowDefaultHeight - 16) / 2), System.Convert.ToInt32((double)(rowDefaultHeight - 16) / 2), 16, 16);
150                 if (rect.Contains(e.Location))
151                 {
152                     //縮起
153                     if (rowCurrent.Contains(e.RowIndex))
154                     {
155                         rowCurrent.Clear();
156                         this.Rows[e.RowIndex].Height = rowDefaultHeight;
157                         this.Rows[e.RowIndex].DividerHeight = rowDefaultDivider;
158 
159                         this.ClearSelection();
160                         collapseRow = true;
161                         this.Rows[e.RowIndex].Selected = true;
162                         if (EControlType == controlType.middle)
163                         {
164                             var oParent = ((MasterControl)this.Parent.Parent);
165                             oParent.Rows[oParent.ExpandRowIndex].Height = rowDefaultHeight * (this.Rows.Count + 4);
166                             oParent.Rows[oParent.ExpandRowIndex].DividerHeight = rowDefaultHeight * (this.Rows.Count + 3);
167                             if (oParent.Rows[oParent.ExpandRowIndex].Height > 500)
168                             {
169                                 oParent.Rows[oParent.ExpandRowIndex].Height = 500;
170                                 oParent.Rows[oParent.ExpandRowIndex].Height = 480;
171                             }
172                         }
173                     }
174                     //展開
175                     else
176                     {
177                         if (!(rowCurrent.Count == 0))
178                         {
179                             var eRow = rowCurrent[0];
180                             rowCurrent.Clear();
181                             this.Rows[eRow].Height = rowDefaultHeight;
182                             this.Rows[eRow].DividerHeight = rowDefaultDivider;
183                             this.ClearSelection();
184                             collapseRow = true;
185                             this.Rows[eRow].Selected = true;
186                         }
187                         rowCurrent.Add(e.RowIndex);
188                         this.ClearSelection();
189                         collapseRow = true;
190                         this.Rows[e.RowIndex].Selected = true;
191                         this.ExpandRowIndex = e.RowIndex;
192                         
193                         this.Rows[e.RowIndex].Height = 66 + rowDefaultHeight * (((DataView)(childView.childGrid[0].DataSource)).Count + 1);
194                         this.Rows[e.RowIndex].DividerHeight = 66 + rowDefaultHeight * (((DataView)(childView.childGrid[0].DataSource)).Count);
195                         //設置一個最大高度
196                         if (this.Rows[e.RowIndex].Height > 500)
197                         {
198                             this.Rows[e.RowIndex].Height = 500;
199                             this.Rows[e.RowIndex].DividerHeight = 480;
200                         }
201                         if (EControlType == controlType.middle)
202                         {
203                             if (this.Parent.Parent.GetType() != typeof(MasterControl))
204                                 return;
205                             var oParent = ((MasterControl)this.Parent.Parent);
206                             oParent.Rows[oParent.ExpandRowIndex].Height = this.Rows[e.RowIndex].Height + rowDefaultHeight * (this.Rows.Count + 3);
207                             oParent.Rows[oParent.ExpandRowIndex].DividerHeight = this.Rows[e.RowIndex].DividerHeight + rowDefaultHeight * (this.Rows.Count + 3);
208                             if (oParent.Rows[oParent.ExpandRowIndex].Height > 500)
209                             {
210                                 oParent.Rows[oParent.ExpandRowIndex].Height = 500;
211                                 oParent.Rows[oParent.ExpandRowIndex].Height = 480;
212                             }
213                         }
214                         //if (EControlType == controlType.outside)
215                         //{
216                         //    //SetControl(this);
217                         //}
218                         //this.Rows[e.RowIndex].Height = rowExpandedHeight;
219                         //this.Rows[e.RowIndex].DividerHeight = rowExpandedDivider;
220                     }
221                     //this.ClearSelection();
222                     //collapseRow = true;
223                     //this.Rows[e.RowIndex].Selected = true;
224                 }
225                 else
226                 {
227                     collapseRow = false;
228                 }
229             }
230             catch (Exception ex)
231             {
232 
233             }
234         }
235 
236         //控件的行重繪事件
237         private void MasterControl_RowPostPaint(object obj_sender, DataGridViewRowPostPaintEventArgs e)
238         {
239             try
240             {
241                 var sender = (DataGridView)obj_sender;
242                 //set childview control
243                 var rect = new Rectangle((int)(e.RowBounds.X + ((double)(rowDefaultHeight - 16) / 2)), (int)(e.RowBounds.Y + ((double)(rowDefaultHeight - 16) / 2)), 16, 16);
244                 if (collapseRow)
245                 {
246                     if (this.rowCurrent.Contains(e.RowIndex))
247                     {
248                         #region 更改點開後背景色 劉金龍
249                         var rect1 = new Rectangle(e.RowBounds.X, e.RowBounds.Y + rowDefaultHeight, e.RowBounds.Width, e.RowBounds.Height - rowDefaultHeight);
250                         using (Brush b = new SolidBrush(Color.FromArgb(164, 169, 143)))
251                         {
252                             e.Graphics.FillRectangle(b, rect1);
253                         } 
254                         #endregion
255                         sender.Rows[e.RowIndex].DividerHeight = sender.Rows[e.RowIndex].Height - rowDefaultHeight;
256                         e.Graphics.DrawImage(RowHeaderIconList.Images[(int)rowHeaderIcons.collapse], rect);
257                         childView.Location = new Point(e.RowBounds.Left + sender.RowHeadersWidth, e.RowBounds.Top + rowDefaultHeight + 5);
258                         childView.Width = e.RowBounds.Right - sender.RowHeadersWidth;
259                         childView.Height = System.Convert.ToInt32(sender.Rows[e.RowIndex].DividerHeight - 10);
260                         childView.Visible = true;
261                     }
262                     else
263                     {
264                         childView.Visible = false;
265                         e.Graphics.DrawImage(RowHeaderIconList.Images[(int)rowHeaderIcons.expand], rect);
266                     }
267                     collapseRow = false;
268                 }
269                 else
270                 {
271                     if (this.rowCurrent.Contains(e.RowIndex))
272                     {
273                         #region 更改點開後背景色 劉金龍
274                         var rect1 = new Rectangle(e.RowBounds.X, e.RowBounds.Y + rowDefaultHeight, e.RowBounds.Width, e.RowBounds.Height - rowDefaultHeight);
275                         using (Brush b = new SolidBrush(Color.FromArgb(164,169,143)))
276                         {
277                             e.Graphics.FillRectangle(b, rect1);
278                         } 
279                         #endregion
280                         sender.Rows[e.RowIndex].DividerHeight = sender.Rows[e.RowIndex].Height - rowDefaultHeight;
281                         e.Graphics.DrawImage(RowHeaderIconList.Images[(int)rowHeaderIcons.collapse], rect);
282                         childView.Location = new Point(e.RowBounds.Left + sender.RowHeadersWidth, e.RowBounds.Top + rowDefaultHeight + 5);
283                         childView.Width = e.RowBounds.Right - sender.RowHeadersWidth;
284                         childView.Height = System.Convert.ToInt32(sender.Rows[e.RowIndex].DividerHeight - 10);
285                         childView.Visible = true;
286                     }
287                     else
288                     {
289                         childView.Visible = false;
290                         e.Graphics.DrawImage(RowHeaderIconList.Images[(int)rowHeaderIcons.expand], rect);
291                     }
292                 }
293                 cModule.rowPostPaint_HeaderCount(sender, e);
294             }
295             catch
296             {
297 
298             }
299         }
300 
301         //控件的滾動條滾動事件
302         private void MasterControl_Scroll(object sender, ScrollEventArgs e)
303         {
304             try
305             {
306                 if (!(rowCurrent.Count == 0))
307                 {
308                     collapseRow = true;
309                     this.ClearSelection();
310                     this.Rows[rowCurrent[0]].Selected = true;
311                 }
312             }
313             catch
314             {
315 
316             }
317         }
318 
319         //控件的單元格選擇事件
320         private void MasterControl_SelectionChanged(object sender, EventArgs e)
321         {
322             try
323             {
324                 if (!(this.RowCount == 0))
325                 {
326                     if (rowCurrent.Contains(this.CurrentRow.Index))
327                     {
328                         foreach (DataGridView cGrid in childView.childGrid)
329                         {
330                             ((DataView)cGrid.DataSource).RowFilter = string.Format(_filterFormat, this[_primaryKey, this.CurrentRow.Index].Value);
331                         }
332                     }
333                 }
334             }
335             catch
336             {
337 
338             }
339         }
340         #endregion
341 
342         #region Private
343         //設置構造函數的參數
344         private void SetMasterControl(DataSet cDataset, controlType eControlType)
345         {
346             //1.控件初始化賦值
347             this.Controls.Add(childView);
348             InitializeComponent();
349             _cDataset = cDataset;
350             childView._cDataset = cDataset;
351             cModule.applyGridTheme(this);
352             Dock = DockStyle.Fill;
353             EControlType = eControlType;
354             this.AllowUserToAddRows = false;
355 
356             //2.經過讀取DataSet裏面的Relations獲得表的關聯關係
357             if (cDataset.Relations.Count <= 0)
358             {
359                 return;
360             }
361             DataRelation oRelates;
362             if (eControlType == controlType.outside)
363             {
364                 oRelates = cDataset.Relations[1];
365                 childView.Add(oRelates.ParentTable.TableName, oRelates.ParentColumns[0].ColumnName, oRelates.ChildColumns[0].ColumnName);
366             }
367             else if (eControlType == controlType.middle)
368             {
369                 oRelates = cDataset.Relations[cDataset.Relations.Count - 1];
370                 childView.Add2(oRelates.ChildTable.TableName);
371             }
372 
373             //3.設置主外鍵對應關係
374             oRelates = cDataset.Relations[0];
375             //主表裏面的值,副表裏面的過濾字段
376             setParentSource(oRelates.ParentTable.TableName,oRelates.ParentColumns[0].ColumnName, oRelates.ChildColumns[0].ColumnName);
377         }
378 
379         private void SetControl(MasterControl oGrid)
380         {
381             oGrid.childView.RemoveControl();
382             //oGrid.childView.Controls.RemoveByKey("ChildrenMaster");
383             //
384             //var oRelates = _cDataset.Relations[1];
385             //oGrid.childView.Add(oRelates.ParentTable.TableName, oRelates.ChildColumns[0].ColumnName);
386             
387 
388             //foreach (var oGridControl in oGrid.Controls)
389             //{
390             //    if (oGridControl.GetType() != typeof(detailControl))
391             //    {
392             //        continue;
393             //    }
394             //    var DetailControl =(detailControl)oGridControl;
395             //    foreach (var odetailControl in DetailControl.Controls)
396             //    {
397             //        if (odetailControl.GetType() != typeof(MasterControl))
398             //        {
399             //            continue;
400             //        }
401             //        var OMasterControl = (MasterControl)odetailControl;
402             //        foreach (var oMasterControl in OMasterControl.Controls)
403             //        {
404             //            if (oMasterControl.GetType() == typeof(detailControl))
405             //            {
406             //                ((detailControl)oMasterControl).Visible = false;
407             //                return;
408             //            }
409             //        }
410             //    }
411             //}
412         }
413 
414         //將List集合轉換成DataTable
415         private DataTable Fill(object obj)
416         {
417             if(!(obj is IList))
418             {
419                 return null;
420             }
421             var objlist = obj as IList;
422             if (objlist == null || objlist.Count <= 0)
423             {
424                 return null;
425             }
426             var tType = objlist[0];
427             DataTable dt = new DataTable(tType.GetType().Name);
428             DataColumn column;
429             DataRow row;
430             System.Reflection.PropertyInfo[] myPropertyInfo = tType.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
431             foreach (var t in objlist)
432             {
433                 if (t == null)
434                 {
435                     continue;
436                 }
437                 row = dt.NewRow();
438                 for (int i = 0, j = myPropertyInfo.Length; i < j; i++)
439                 {
440                     System.Reflection.PropertyInfo pi = myPropertyInfo[i];
441                     string name = pi.Name;
442                     if (dt.Columns[name] == null)
443                     {
444                         column = new DataColumn(name, pi.PropertyType);
445                         dt.Columns.Add(column);
446                     }
447                     row[name] = pi.GetValue(t, null);
448                 }
449                 dt.Rows.Add(row);
450             }
451             return dt;
452         }
453         #endregion
454     }
View Code

 

二、detailControl變量做爲一個容器用來保存子表格,代碼以下:測試

 1 public class detailControl : Ewin.Client.Frame.Controls.EwinPanel
 2     {
 3         #region 字段
 4         public List<DataGridView> childGrid = new List<DataGridView>();
 5         public DataSet _cDataset;
 6         #endregion
 7 
 8         #region 方法
 9         public void Add(string tableName, string strPrimaryKey, string strForeignKey)
10         {
11             //TabPage tPage = new TabPage() { Text = pageCaption };
12             //this.Controls.Add(tPage);
13             var newGrid = new MasterControl(_cDataset, controlType.middle) { Dock = DockStyle.Fill, DataSource = new DataView(_cDataset.Tables[tableName]) };
14             newGrid.setParentSource(tableName, strPrimaryKey, strForeignKey);//設置主外鍵
15             //newGrid.Name = "ChildrenMaster";
16             //tPage.Controls.Add(newGrid);
17             this.Controls.Add(newGrid);
18             //this.BorderStyle = BorderStyle.FixedSingle;
19             cModule.applyGridTheme(newGrid);
20             cModule.setGridRowHeader(newGrid);
21             newGrid.RowPostPaint += cModule.rowPostPaint_HeaderCount;
22             childGrid.Add(newGrid);
23         }
24 
25         public void Add2(string tableName)
26         {
27             //TabPage tPage = new TabPage() { Text = pageCaption };
28             //this.Controls.Add(tPage);
29             DataGridView newGrid = new Ewin.Client.Frame.Controls.EwinGrid() { Dock = DockStyle.Fill, DataSource = new DataView(_cDataset.Tables[tableName]) };
30             newGrid.AllowUserToAddRows = false;
31             //tPage.Controls.Add(newGrid);
32             this.Controls.Add(newGrid);
33             cModule.applyGridTheme(newGrid);
34             cModule.setGridRowHeader(newGrid);
35             newGrid.RowPostPaint += cModule.rowPostPaint_HeaderCount;
36             childGrid.Add(newGrid);
37         }
38 
39         public void RemoveControl()
40         {
41             this.Controls.Remove(childGrid[0]);
42             childGrid.Clear();
43         }
44         #endregion
45 
46     }
View Code

 

三、cModule.cs用來設置樣式this

  1 namespace Ewin.Client.Frame.UcGrid
  2 {
  3     /// <summary>
  4     /// 摺疊控件樣式以及行數操做類
  5     /// </summary>
  6     sealed class cModule
  7     {
  8         #region CustomGrid
  9         static System.Windows.Forms.DataGridViewCellStyle dateCellStyle = new System.Windows.Forms.DataGridViewCellStyle { Alignment = DataGridViewContentAlignment.MiddleRight };
 10         static System.Windows.Forms.DataGridViewCellStyle amountCellStyle = new System.Windows.Forms.DataGridViewCellStyle { Alignment = DataGridViewContentAlignment.MiddleRight, Format = "N2" };
 11         static System.Windows.Forms.DataGridViewCellStyle gridCellStyle = new System.Windows.Forms.DataGridViewCellStyle
 12         {
 13             Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft,
 14             BackColor = System.Drawing.Color.FromArgb(System.Convert.ToInt32(System.Convert.ToByte(79)), System.Convert.ToInt32(System.Convert.ToByte(129)), System.Convert.ToInt32(System.Convert.ToByte(189))),
 15             Font = new System.Drawing.Font("Segoe UI", (float)(10.0F), System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, System.Convert.ToByte(0)),
 16             ForeColor = System.Drawing.SystemColors.ControlLightLight,
 17             SelectionBackColor = System.Drawing.SystemColors.Highlight,
 18             SelectionForeColor = System.Drawing.SystemColors.HighlightText,
 19             WrapMode = System.Windows.Forms.DataGridViewTriState.True
 20         };
 21         static System.Windows.Forms.DataGridViewCellStyle gridCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle
 22         {
 23             Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft,
 24             BackColor = System.Drawing.SystemColors.ControlLightLight,
 25             Font = new System.Drawing.Font("Segoe UI", (float)(10.0F), System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, System.Convert.ToByte(0)),
 26             ForeColor = System.Drawing.SystemColors.ControlText,
 27             SelectionBackColor = System.Drawing.Color.FromArgb(System.Convert.ToInt32(System.Convert.ToByte(155)), System.Convert.ToInt32(System.Convert.ToByte(187)), System.Convert.ToInt32(System.Convert.ToByte(89))),
 28             SelectionForeColor = System.Drawing.SystemColors.HighlightText,
 29             WrapMode = System.Windows.Forms.DataGridViewTriState.False
 30         };
 31         static System.Windows.Forms.DataGridViewCellStyle gridCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle
 32         {
 33             Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft,
 34             BackColor = System.Drawing.Color.WhiteSmoke,
 35             Font = new System.Drawing.Font("Segoe UI", (float)(10.0F), System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, System.Convert.ToByte(0)),
 36             ForeColor = System.Drawing.SystemColors.WindowText,
 37             SelectionBackColor = System.Drawing.Color.FromArgb(System.Convert.ToInt32(System.Convert.ToByte(155)), System.Convert.ToInt32(System.Convert.ToByte(187)), System.Convert.ToInt32(System.Convert.ToByte(89))),
 38             SelectionForeColor = System.Drawing.SystemColors.HighlightText,
 39             WrapMode = System.Windows.Forms.DataGridViewTriState.True
 40         };
 41 
 42         //設置表格的主題樣式
 43         static public void applyGridTheme(DataGridView grid)
 44         {
 45             grid.AllowUserToAddRows = false;
 46             grid.AllowUserToDeleteRows = false;
 47             grid.BackgroundColor = System.Drawing.SystemColors.Window;
 48             grid.BorderStyle = System.Windows.Forms.BorderStyle.None;
 49             grid.ColumnHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Single;
 50             grid.ColumnHeadersDefaultCellStyle = gridCellStyle;
 51             grid.ColumnHeadersHeight = 32;
 52             grid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
 53             grid.DefaultCellStyle = gridCellStyle2;
 54             grid.EnableHeadersVisualStyles = false;
 55             grid.GridColor = System.Drawing.SystemColors.GradientInactiveCaption;
 56             //grid.ReadOnly = true;
 57             grid.RowHeadersVisible = true;
 58             grid.RowHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Single;
 59             grid.RowHeadersDefaultCellStyle = gridCellStyle3;
 60             grid.Font = gridCellStyle.Font;
 61         }
 62 
 63         //設置表格單元格樣式
 64         static public void setGridRowHeader(DataGridView dgv, bool hSize = false)
 65         {
 66             dgv.TopLeftHeaderCell.Value = "NO ";
 67             dgv.TopLeftHeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
 68             dgv.AutoResizeRowHeadersWidth(DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders);
 69             foreach (DataGridViewColumn cCol in dgv.Columns)
 70             {
 71                 if (cCol.ValueType.ToString() == typeof(DateTime).ToString())
 72                 {
 73                     cCol.DefaultCellStyle = dateCellStyle;
 74                 }
 75                 else if (cCol.ValueType.ToString() == typeof(decimal).ToString() || cCol.ValueType.ToString() == typeof(double).ToString())
 76                 {
 77                     cCol.DefaultCellStyle = amountCellStyle;
 78                 }
 79             }
 80             if (hSize)
 81             {
 82                 dgv.RowHeadersWidth = dgv.RowHeadersWidth + 16;
 83             }
 84             dgv.AutoResizeColumns();
 85         }
 86 
 87         //設置表格的行號
 88         static public void rowPostPaint_HeaderCount(object obj_sender, DataGridViewRowPostPaintEventArgs e)
 89         {
 90             try
 91             {
 92                 var sender = (DataGridView)obj_sender;
 93                 //set rowheader count
 94                 DataGridView grid = (DataGridView)sender;
 95                 string rowIdx = System.Convert.ToString((e.RowIndex + 1).ToString());
 96                 var centerFormat = new StringFormat();
 97                 centerFormat.Alignment = StringAlignment.Center;
 98                 centerFormat.LineAlignment = StringAlignment.Center;
 99                 Rectangle headerBounds = new Rectangle(e.RowBounds.Left, e.RowBounds.Top,
100                     grid.RowHeadersWidth, e.RowBounds.Height - sender.Rows[e.RowIndex].DividerHeight);
101                 e.Graphics.DrawString(rowIdx, grid.Font, SystemBrushes.ControlText,
102                     headerBounds, centerFormat);
103             }
104             catch (Exception ex)
105             {
106 
107             }
108         }
109         #endregion
110     }
111 
112     /// <summary>
113     /// 控件類型,是最外層的表格仍是中間層的表格
114     /// </summary>
115     public enum controlType
116     {
117         outside = 0,
118         middle = 1
119     }
120 
121     /// <summary>
122     /// 展開圖標
123     /// </summary>
124     public enum rowHeaderIcons
125     {
126         expand = 0,
127         collapse = 1
128     }
129 }
View Code

  

四、From頁面調用spa

#region 使用方法一
            //var oDataSet = GetDataSet();
            //
            //masterDetail = new MasterControl(oDataSet, controlType.outside); 
            #endregion

            #region 使用方法二
            var dicRelateData1 = new Dictionary<string, string>();
            var dicRelateData2 = new Dictionary<string, string>();
            dicRelateData1.Add("Menu_ID","Menu_ID");//表格一和表格二之間的主外鍵關係
            dicRelateData2.Add("Menu_Name2","Menu_Name2");//表格二和表格三之間的主外鍵關係
masterDetail = new MasterControl(GetDataSource(), GetDataSource2(), GetDataSource3(), dicRelateData1, dicRelateData2, controlType.outside); #endregion panelView.Controls.Add(masterDetail);

    

 昨天應領導要求,摺疊控件增長了摺疊線的效果,看起來有沒有更加像模像樣了。~~~3d

其實就在行重繪事件private void MasterControl_RowPostPaint(object obj_sender, DataGridViewRowPostPaintEventArgs e)裏面增長了以下代碼:code

using (Pen p = new Pen(Color.GhostWhite))
{
var iHalfWidth = (e.RowBounds.Left + sender.RowHeadersWidth) / 2;
var oPointHLineStart = new Point(rect1.X + iHalfWidth, rect1.Y);
var oPointHLineEnd = new Point(rect1.X + iHalfWidth, rect1.Y + rect1.Height / 2);
e.Graphics.DrawLine(p, oPointHLineStart, oPointHLineEnd);
//摺疊線
e.Graphics.DrawLine(p, oPointHLineEnd, new Point(oPointHLineEnd.X + iHalfWidth, oPointHLineEnd.Y));
}component

效果以下:

 

2015-07-01

PS:原覺得CS的控件你們不會太感興趣,這兩天不少園友找我要源碼,其實並不是捨不得將源碼共享,只是不少東西融入到項目中了很難分離出來,須要時間整理,望理解。知道這麼多園友對CS的控件也感興趣,我就抽時間整理了下摺疊控件的Demo。本着你們共同進步的原則將源碼共享出來。好的東西就要共享,咱.Net也要慢慢走共享開源路線哈~~

源碼下載

相關文章
相關標籤/搜索