1. 程式人生 > >Winform系列——好看的DataGridView摺疊控制元件

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

      來園子幾年了,第一次寫部落格。以前看到別人的部落格就在想:這些人怎麼能有這麼多時間整理這麼多知識,難道他們不用工作、不用寫程式碼、不用交付測試?隨著工作閱歷的增加,發現其實並不是時間的問題,關鍵一個字:懶。其實寫部落格的好處大傢伙都心知肚明。呵呵,第一次寫就這麼多廢話,看樣子真是年紀大了。

  其實自己之前的5年也一直是做BS的系統,現在剛換的一家公司需要做一個CS的產品。屌了,自己之前一點經驗都沒有呢,沒辦法,既來之則安之,學唄。於是乎各種百度、各種視訊,各種資料。系統其中一個需求就是需要表格摺疊顯示,這如果在BS裡面那太簡單了,JqGrid預設都自帶,可是DataGridview不支援摺疊啊,咋辦。自己封裝唄,於是乎又是各種百度,這種原始碼學習。最後借鑑原始碼封了這麼一個東西,發出來分享下,也能讓自己加深印象。首先不多說,上圖:

大概的效果就是這樣。上程式碼。

1、首先重寫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的順序不能顛倒,必須先新增一、二級的表關聯,再新增二、三級的表關聯 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");

相關推薦

Winform系列——好看DataGridView摺疊控制元件

      來園子幾年了,第一次寫部落格。以前看到別人的部落格就在想:這些人怎麼能有這麼多時間整理這麼多知識,難道他們不用工作、不用寫程式碼、不用交付測試?隨著工作閱歷的增加,發現其實並不是時間的問題,關鍵一個字:懶。其實寫部落格的好處大傢伙都心知肚明。呵呵,第一次寫就這麼多廢話,看樣子真是年紀大了。   

WinForm系列(一)-控制元件listview

listview控制元件使用的時候發現不如datagview控制元件好使,很多時候通過dataset集合獲取後,顯示的效果不是自己想要的,比如獲取一些資料庫表名後,顯示的時候很亂。 比如想分行顯示,想一行顯示幾個的時候,用起來不是很好用。 如載入一個ds 函式如下:

Winform系列——好用的DataGridview過濾控制元件(表格的高階搜尋功能)

using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Drawing; using System.Data; using Syste

WinForm下編寫分頁控制元件,實現DataGridView的分頁效果

     前幾天做C/S專案的時候用到了分頁查詢,所以就想去網上找一些封裝好的分頁控制元件,類似BS專案中的那種。但是找了好幾個都不是特別的好,沒有自己想要的。而且WinForm 裡面的DataGridView也不像WebForm裡面的GridView那樣有自帶的分

[工作札記]03: 微軟Winform窗體中ListView、DataGridView控制元件的Bug,會導致程式編譯失敗,影響範圍:到最新的.net4.7.2都有

工作中,我們發現了微軟.net WinForm的一個Bug,會導致窗體設計器自動生成的程式碼失效,這個Bug從.net4.5到最新的.net4.7.2都存在,一直沒有解決。最初是我在教學工作中發現的,後來工作的時候該Bug也常現。 重現步驟:   使用VisualStudio2013/2015/2017/

分享一個Winform下的分頁控制元件

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

c#winform跨執行緒操作控制元件的一種方法,InvokeRequired

  在winform裡面如果有建立新執行緒的話,線上程裡面直接操作控制元件或修改控制元件的屬性是不允許的,雖然有辦法讓程式執行時忽略跨執行緒可能產生的問題,從而解決;但是從科學的角度看,該辦法並不可取,所以我就用了InvokeRequired的辦法解決跨執行緒操作問題。  

一個好看的時間控制元件

Android 一個好看的時間控制元件 1.依賴包 compile 'com.wx.wheelview:wheelview:1.3.3' 2.在佈局中使用 <LinearLayout android:layout_width="60dp

一款好看的日曆控制元件

android 一款好看的日曆控制元件 1.依賴包 compile 'com.prolificinteractive:material-calendarview:1.4.0' 佈局中的使用: <com.prolificinteractive.materialcal

【轉】WinForm介面開發之佈局控制元件"WeifenLuo.WinFormsUI.Docking"的使用

本篇介紹Winform程式開發中的佈局介面的設計,介紹如何在我的共享軟體中使用佈局控制元件"WeifenLuo.WinFormsUI.Docking"。 佈局控制元件"WeifenLuo.WinFormsUI.Docking"是一個非常棒的開源控制元件,用過的人都深有體會,

C#、winform、wpf將類控制元件放進工具箱裡

有時我們需要將vs自帶的控制元件的某一些方法或屬性進行一些修改,我們通常會新建一個類來繼承它然後對它的方法或屬性進行修改,那麼我們如何將修改完成的控制元件類變成視覺化控制元件放到工具箱中便於使用呢? 很簡單,只要在修改完成的類上加上[ToolboxBitmap(typeof(控制元件))]然後再生成解決方案就

如何在WINFORM中彈出一個又控制元件的對話方塊 能給個簡單的示範C#程式碼嗎 以及一些小問題 菜鳥想學

如何在WINFORM中彈出一個又控制元件的對話方塊  能給個簡單的示範C#程式碼嗎順便問問 這段程式碼是啥意思啊        private void btn_catchMe_Click(object sender, System.EventArgs e)        {

在.Net的WinForm開發中如何實現控制元件隨窗體大小的改變而自動適應其改變

在設計可供使用者調整大小的窗體時,如何實現該窗體上的控制元件也應能正確地隨窗體的改變而自動調整大小並且能重新定位?此時就要藉助控制元件的.Anchor屬性。Anchor屬性定義控制元件的定位點位置。當控制元件錨定到某個窗體時,如果該窗體的大小被調整,那麼該控制元件維持它與定位

winform 中panel動態新增控制元件座標原點問題

問題描述 最近在寫winform程式的時候遇到一個小問題,目標效果是類似QQ的聊天對話方塊,每傳送一條訊息會在介面上顯示傳送方的頭像、傳送氣泡、以及訊息內容,如圖 按照原來的想法,每條訊息都是一個獨立的panel,然後在主介面的大的panel中add每一

Win10系列:C#應用控制元件進階4

多邊形 若要繪製多邊形需要用到Polygon元素,並通過定義一系列的點繪製多邊形。Polygon型別的物件有Points屬性, 這個屬性用來定義組成邊的點集。在前臺程式碼中,使用空格分隔各個點,然後利用逗號分隔座標點來定義點座標。不必為了將起點和終點指定為相同的值而宣告閉合點,Polygon類假設要定義閉合

Win10系列:C#應用控制元件進階10

EllipseGeometry EllipseGeometry控制元件可以用於繪製橢圓,通過定義EllipseGeometry控制元件的Center屬性確定橢圓的圓心座標,使用此控制元件的RadiusX 和RadiusY屬性分別定義橢圓X軸、Y軸的半徑長度。下面將演示如何使用EllipseGeometry

Win10系列:C#應用控制元件進階7

PathGeometry 前面介紹了Path的使用方法,接下來介紹PathGeometry類。PathGeometry提供了描繪由弧線、曲線和直線組成的多個複雜圖形的方法。PathGeometry的核心是PathFigure物件集合,PathFigure自身由一個或多個PathSegment子類物件組成,每

Win10系列:C#應用控制元件進階6

路徑 路徑(Path)可以用來定義任意形狀的曲線和幾何圖形,當然這種任意性也帶來了複雜性。為了方便的繪製幾何圖形,微軟在Visual Studio 2012安裝包中為程式開發者提供了免費的Blend for Visual Studio設計工具,利用這個介面設計工具可以方便的繪製圖形。 而對於開發者而言,有

Win10系列:C#應用控制元件進階9

RectangleGeometry 在使用RectangleGeometry控制元件繪製矩形時,矩形的位置和尺寸由Rect屬性定義,該屬性指定矩形的相對位置、高度和寬度。Rect有四個引數,前兩個引數表示矩形左上角的位置,後兩個引數分別表示矩形的寬和高。下面將通過示例演示如何使用RectangleGeome

Win10系列:C#應用控制元件進階8

LineGeometry LineGeometry控制元件通過指定直線的起點和終點來定義線。LineGeometry物件無法進行自我繪製,因此同樣需要使用 Path元素來輔助呈現。LineGeometry與Line物件很相似,它們都沒有內部面積,不過兩者在用法上有些區別,通過定義LineGeometry的S