C# c1FlexGrid 幫助文檔
Value-Mapped Lists(值映射列表)
功能描述:上述財產的ComboList確保單元格的值是從名單中挑選。由用戶選擇的值轉換成列的適當類型和存儲在網格,完全一樣,如果用戶已輸入的值。
在許多情況下,細胞能夠承擔來自明確列出的值,但是你想顯示一個用戶的實際價值的版本。例如,如果一個列包含的產品代碼,您可能要存儲的代碼,但顯示的產品名稱來代替。
這是通過的DataMap財產。此屬性包含一個引用到的IDictionary對象之間建立什么是存儲在網格中,什么是可見的用戶(IDictionary接口是System.Collections命名空間中定義,並得到其他Hashtable類中實現)映射。
例如,下面的代碼創建了一個數據映射,它包含顏色值,他們的名字。這些顏色都存儲在網格中,他們的名字所顯示的用戶:
功能示例:
1 System.Collections.Hashtable dtMap = new System.Collections.Hashtable(); 2 3 dtMap.Add(Color.Red, "Apple"); 4 5 dtMap.Add(Color.Green, "Forest"); 6 7 dtMap.Add(Color.Blue, "Sky"); 8 9 dtMap.Add(Color.Black, "Coal"); 10 11 dtMap.Add(Color.White, "Snow"); 12 13 _flex.Cols[1].DataType = typeof(Color); 14 15 _flex.Cols[1].DataMap = dtMap;
實現IDictionary的任何類可以作為一個DataMap使用。例如,哈希表,ListDictionary的,和SortedList都提供了有效的數據地圖。所不同的是,當他們在編輯欄使用時,在下拉列表中項目的順序將取決於類。
各種各樣的SortedList類的重點項目,Hashtable的使用任意命令,ListDictionary的保持在哪些項目被添加到列表的順序。正因為如此,ListDictionary的通常是為DataMaps的最佳選擇。
請注意,在數據映射的鍵必須為同一類型的細胞被編輯。例如,如果一個列包含短整數(Int16的),那么任何數據列關聯應該有短整數鍵地圖。作為密鑰不會正常工作整數(Int32的)。
下面的例子顯示的區別:
1 private void Form1_Load(object sender, System.EventArgs e); 2 3 { 4 5 // Sorts by key. 6 7 System.Collections.SortedList sl = new System.Collections.SortedList(); 8 9 sl.Add("0", "Zero"); 10 11 sl.Add("1", "One"); 12 13 sl.Add("2", "Two"); 14 15 sl.Add("3", "Three"); 16 17 18 19 // Keeps Add order. 20 21 System.Collections.Specialized.ListDictionary ld = new System.Collections.Specialized.ListDictionary(); 22 23 ld.Add(0, "Zero"); 24 25 ld.Add(1, "One"); 26 27 ld.Add(2, "Two"); 28 29 ld.Add(3, "Three"); 30 31 32 33 // Arbitrary order. 34 35 System.Collections.Hashtable ht = new System.Collections.Hashtable(); 36 37 ht.Add(0, "Zero"); 38 39 ht.Add(1, "One"); 40 41 ht.Add(2, "Two"); 42 43 ht.Add(3, "Three"); 44 45 46 47 _flex.Cols[1].DataMap = sl; 48 49 _flex.Cols[1].Caption = "SortedList"; 50 51 _flex.Cols[2].DataMap = ld; 52 53 _flex.Cols[2].Caption = "ListDictionary"; 54 55 _flex.Cols[3].DataMap = ht; 56 57 _flex.Cols[3].Caption = "HashTable"; 58 59 }
Cell Buttons (細胞按鈕)
功能描述:某些類型的細胞,可能需要較復雜的編輯文本框或下拉列表等。例如,如果一個列包含文件名稱或一種顏色,它應該是一個對話框編輯。
在這種情況下,你應該設置ComboList屬性省略號(“...”)。該控件將顯示一個按鈕,旁邊的單元格,將觸發CellButtonClick事件當用戶點擊就可以了。您可以捕獲的事件,顯示該對話框,並更新用戶的選擇單元格的內容。
如果您添加一個省略號前管道字符,那么用戶將被允許進入細胞編輯輸入單元格內容。
默認情況下,細胞按鈕顯示省略號。您可以指定圖片的單元格按鈕使用CellButtonImage財產。
下面演示了如何使用手機的按鈕顯示選擇列中的某個顏色的顏色選擇器對話框的例子。
功能示例:
1 // Set up color column. 2 3 Column c = _flex.Cols[1]; 4 5 c.DataType = typeof(Color); 6 7 8 9 // Show cell button. 10 11 c.ComboList = "...";
此代碼設置列,以便用戶可以點擊一個按鈕,然后從對話框中的顏色。下一步是處理的代碼單元格按鈕上點擊:
1 private void _flex_CellButtonClick( object sender, RowColEventArgs e) 2 3 { 4 5 // Create color picker dialog. 6 7 ColorDialog clrDlg = new ColorDialog(); 8 9 10 11 // Initialize the dialog. 12 13 if (_flex[e.Row, e.Col] == typeof(Color)) 14 15 { 16 17 clrDlg.Color = (Color)_flex[e.Row, e.Col]; 18 19 } 20 21 22 23 // Get new color from dialog and assign it to the cell. 24 25 if (clrDlg.ShowDialog() == DialogResult.OK) 26 27 { 28 29 _flex[e.Row, e.Col] = clrDlg.Color; 30 31 } 32 33 }
Masks(面具)
該C1FlexGrid控件還支持蒙面編輯。使用這種類型的編輯輸入掩碼提供一個模板,並自動驗證用戶類型作為輸入。面具是指定的EditMask屬性,可以用正則文本字段和下拉式組合領域。
面膜字符串有兩種類型的字符:字面字符,成為輸入部分和模板字符,這為屬於特定類別中的字符為占位符(例如,數字或字母)。例如,下面的代碼指定一個“(999)999-9999”,以第一列,它包含電話號碼的編輯掩碼(數字“9”是一個占位符,對於任何數字的縮寫):
代碼示例:
1 // Set up a phone number edit mask. 2 3 _flex.Cols[1].EditMask = "(999) 999-9999";
EditMask屬性設置為一個非空字符串會導致它使用內置的蒙面編輯器,即使該列包含日期/時間值(通常,一個DateTimePicker控件用於編輯這些列)。這是特別方便,如果您有DateTime列持有時間(無日期)。在這種情況下,可以設置以下屬性,以使用,而不是在DateTimePicker控制蒙面編輯:
1 _flex.Cols[1].DataType = typeof(DateTime); 2 3 _flex.Cols[1].Format = "hh:mm tt"; 4 5 _flex.Cols[1].EditMask = "99:99 LL";
對話框中輸入掩碼可以通過菜單或任務列通過C1FlexGrid列編輯器。
在任務菜單•列,單擊編輯掩碼框中的省略號按鈕。
•在C1FlexGrid欄編輯器,找到在左窗格中的EditMask屬性,單擊省略號按鈕旁邊。
注意:在輸入掩碼列的特定對話框,只會改變所選列EditMask屬性。
有關用來建立遮罩字串語法的詳細信息,請參閱參考部分EditMask控制的財產。
如果在同一列中不同的細胞需要不同的面具,捕獲BeforeEdit事件,並設置EditMask屬性為當前單元格適當的值。
Validation(驗證)
功能描述:在許多情況下,編輯口罩本身是不夠的,以確保用戶輸入的數據是有效的。例如,一個面具不會讓你指定一個可能值的范圍,或驗證當前單元格在另一個單元格的內容為基礎。
在這種情況下,捕獲ValidateEdit事件,看看在Editor.Text屬性中包含的值是當前單元格有效的項目(在這一點上,細胞仍然在它的原始值)。如果輸入是無效的,取消參數設置為true,將繼續留在格編輯,直到用戶輸入一個有效的輸入模式。
例如,下面的代碼驗證成貨幣列輸入,以確保輸入的值在1000和10000是:
代碼示例:

1 private void _flex_ValidateEdit( object sender, ValidateEditEventArgs e) 2 3 { 4 5 6 7 // Validate amounts. 8 9 if (_flex.Cols[e.Col].DataType == typeof(Decimal)) 10 11 { 12 13 try 14 15 { 16 17 Decimal dec = Decimal.Parse(_flex.Editor.Text); 18 19 if ( dec < 1000 || dec > 10000 ) 20 21 { 22 23 MessageBox.Show("Value must be between 1,000 and 10,000"); 24 25 e.Cancel = true; 26 27 } 28 29 } 30 31 catch 32 33 { 34 35 MessageBox.Show("Value not recognized as a Currency"); 36 37 e.Cancel = true; 38 39 } 40 41 } 42 43 }
Merged Table Headers(合並表頭)
功能描述:要創建合並表頭,你必須首先設置網格的AllowMerging屬性FixedOnly。然后,指定的行和列要合並設置的行和列的AllowMerging屬性。最后,分配到頁眉文本細胞,使細胞要合並有相同的內容。
下面的代碼顯示了一個例子:
代碼示例:

1 private void Form1_Load(System.object sender, System.EventArgs e) 2 3 { 4 5 int i; 6 7 8 9 // Initialize the control. 10 11 _flex.Styles.Normal.WordWrap = true; 12 13 _flex.Cols.Count = 9; 14 15 _flex.Rows.Fixed = 2; 16 17 _flex.AllowMerging = C1.Win.C1FlexGrid.AllowMergingEnum.FixedOnly; 18 19 20 21 // Create row headers. 22 23 _flex.Rows[0].AllowMerging = true; 24 25 26 27 // Merge the four cells with same contents. 28 29 C1.Win.C1FlexGrid.CellRange rng = _flex.GetCellRange(0, 1, 0, 4); 30 31 rng.Data = "North"; 32 33 34 35 // Merge the four cells with same contents. 36 37 rng = _flex.GetCellRange(0, 5, 0, 8); 38 39 rng.Data = "South"; 40 41 for ( i = 1 ; i <= 4; i++) 42 43 { 44 45 _flex[1, i] = "Qtr " + i; 46 47 _flex[1, i + 4] = "Qtr " + i; 48 49 } 50 51 52 53 // Create the column header. 54 55 _flex.Cols[0].AllowMerging = true; 56 57 58 59 // Merge the two cells with same contents. 60 61 rng = _flex.GetCellRange(0, 0, 1, 0); 62 63 rng.Data = "Sales by Product"; 64 65 66 67 // Align and autosize the cells. 68 69 _flex.Styles.Fixed.TextAlign = C1.Win.C1FlexGrid.TextAlignEnum.CenterCenter; 70 71 _flex.AutoSizeCols(1, _flex.Cols.Count - 1, 10); 72 73 } 74 75 This is the result: 76 77 78 79
This is the result:
Merged Data Views(合並數據)
功能描述:
單元格合並的工作方式相同,當網格綁定到數據源。下面的代碼顯示了綁定到數據源在設計時一格一個例子。如需綁定到數據源的信息,請參見綁定到數據源。
代碼示例:

1 private void Form1_Load( System.object sender, System.EventArgs e) 2 3 { 4 5 int i; 6 7 8 9 // Set up cell merging. 10 11 _flex.AllowMerging = C1.Win.C1FlexGrid.AllowMergingEnum.RestrictCols; 12 13 for (int i = _flex.Cols.Fixed; i <= _flex.Cols.Count - 1; i++) 14 15 { 16 17 _flex.Cols(i).AllowMerging = true; 18 19 } 20 21 }
This is the result:
Creating Subtotals(創建分類匯總)
功能描述:該C1FlexGrid.Subtotal方法將包含在常規(非小計)行的匯總數據匯總行。
小計支援階層集合體。例如,如果你的網格包含銷售數據,您可能獲得總銷售額合計按產品,區域,和銷售人員的數字。下面的代碼說明了這一點
代碼示例:

1 private void ShowTotals() 2 3 { 4 5 // Show OutlineBar on column 0. 6 7 _flex.Tree.Column = 0; 8 9 _flex.Tree.Style = TreeStyleFlags.Simple; 10 11 12 13 // Clear existing subtotals. 14 15 _flex.Subtotal(AggregateEnum.Clear); 16 17 18 19 // Get a Grand total (use -1 instead of column index). 20 21 _flex.Subtotal(AggregateEnum.Sum, -1, -1, 3, "Grand Total"); 22 23 24 25 // Total per Product (column 0). 26 27 _flex.Subtotal(AggregateEnum.Sum, 0, 0, 3, "Total {0}"); 28 29 30 31 // Total per Region (column 1). 32 33 _flex.Subtotal(AggregateEnum.Sum, 1, 1, 3, "Total {0}"); 34 35 36 37 // Size column widths based on content. 38 39 _flex.AutoSizeCols(); 40 41 }
當C1FlexGrid.Subtotal方法添加行的匯總信息,它會自動分配小計樣式新行(有內置的5個分類匯總級別樣式)。您可以通過更改在與風格編輯器或代碼設計師的大綱樣式屬性的分類匯總行的外觀。例如:

1 // Set styles for subtotals. 2 3 CellStyle cs; 4 5 cs = _flex.Styles[CellStyleEnum.GrandTotal]; 6 7 cs.BackColor = Color.Black; 8 9 cs.ForeColor = Color.White; 10 11 cs.Font = new Font(Font, FontStyle.Bold); 12 13 14 15 cs = _flex.Styles[CellStyleEnum.Subtotal0]; 16 17 cs.BackColor = Color.DarkRed; 18 19 cs.ForeColor = Color.White; 20 21 cs.Font = new Font(Font, FontStyle.Bold); 22 23 24 25 cs = _flex.Styles[CellStyleEnum.Subtotal1]; 26 27 cs.BackColor = Color.DarkBlue; 28 29 cs.ForeColor = Color.White;
After executing this code, the grid would look like this:
在總計行中包含的所有產品,地區和銷售人員的總銷售額。它是一個用在方法調用的C1FlexGrid.Subtotal groupOn參數為-1。另按產品分類匯總顯示和地區的總銷售額。他們創建的一個值0,為groupOn參數1。
您也可以計算總量比其他款項(例如,平均值或百分比),並計算每行數總量(例如,毛保費及凈銷售額)。
由小計小計行方法建立在三個方面有所不同規則的行:
1。小計行可以被自動刪除通過調用參數與flexSTClear小計方法。這是非常有用的數據提供,用戶可以移動列,並重新對數據進行排序,因此有必要重新計算分類匯總的動態視圖。
2。小計行可作為節點的一個大綱,讓您折疊和展開的行群體提出一個數據概述或透露其細節。要看到樹的輪廓,你需要設置列和Tree.Style屬性來定義的位置和輪廓樹的外觀。
3。小計行可以被視為在一個樹節點。你可以通過任何節點屬性分類匯總行中的節點對象。
4。當網格綁定到數據源,小計行不符合實際的數據。如果你在數據源中的光標,次全行會被忽略在網格中。
大綱樹允許用戶通過折疊和展開的節點上點擊網格的部分。您可以使用大綱樹來顯示多種類型的信息,不僅總量。下一個主題演示如何創建一個自定義大綱樹來顯示目錄信息。
Creating Custom Trees(創建自定義樹)
功能描述:創造輪廓樹不使用小結的方法中,你需要遵循這些步驟:
1。添加排電網。
2。把一些行轉換成輪廓節點IsNode把他們的財產是真實的。
3。得到節點對象為每個節點排並設置其水平產權界定節點的位置在樹上的層次結構。更高的價值意味着節點是更深的(更)為輪廓縮進樹。
例如,下面的代碼創建一個目錄樹:
代碼示例:
1 // add these using statements at the top of the form 2 3 using System; 4 5 using System.Collections.Generic; 6 7 using System.ComponentModel; 8 9 using System.Data; 10 11 using System.Drawing; 12 13 using System.Text; 14 15 using System.Windows.Forms; 16 17 using System.IO; 18 19 using C1.Win.C1FlexGrid; 20 21 22 23 private void Form1_Load(object sender, EventArgs e) 24 25 { 26 27 28 29 // Initialize grid layout. 30 31 _flex.Cols.Fixed = 0; 32 33 _flex.Cols.Count = 1; 34 35 _flex.Rows.Count = 1; 36 37 _flex.ExtendLastCol = true; 38 39 _flex.Styles.Normal.TextAlign = TextAlignEnum.LeftCenter; 40 41 _flex.Styles.Normal.Border.Style = BorderStyleEnum.None; 42 43 44 45 // Initialize outline tree. 46 47 _flex.Tree.Column = 0; 48 49 _flex.Tree.Style = TreeStyleFlags.SimpleLeaf; 50 51 _flex.Tree.LineColor = Color.DarkBlue; 52 53 54 55 // Populate the grid. 56 57 AddDirectory(@"c:\\", 0); 58 59 }
上面的代碼初始化電網布局,並調用AddDirectory例程,並在網格的填充和設立樹狀結構的工作:
1 private void AddDirectory(string dir, int level) 2 3 { 4 5 // add this directory 6 7 string thisDir = Path.GetFileName(dir); 8 9 if (thisDir.Length == 0) { thisDir = dir; } 10 11 _flex.AddItem(thisDir); 12 13 //make this new row a node 14 15 Row row = _flex.Rows[_flex.Rows.Count - 1]; 16 17 row.IsNode = true; 18 19 //set node level 20 21 Node nd = row.Node; 22 23 nd.Level = level; 24 25 // add files in this directory 26 27 int cnt = 0; 28 29 Row r; 30 31 32 33 foreach (string file in Directory.GetFiles(dir)) 34 35 { 36 37 _flex.AddItem(Path.GetFileName(file).ToLower()); 38 39 //mark the row without child row as node 40 41 r = _flex.Rows[_flex.Rows.Count - 1]; 42 43 r.IsNode = true; 44 45 r.Node.Level = level + 1; 46 47 cnt = cnt + 1; 48 49 if (cnt > 10) break; 50 51 } 52 53 54 55 // add subdirectories (up to level 4) 56 57 if (level <= 4) 58 59 { 60 61 cnt = 0; 62 63 foreach (string subdir in Directory.GetDirectories(dir)) 64 65 { 66 67 AddDirectory(subdir, level + 1); 68 69 cnt = cnt + 1; 70 71 if (cnt > 10) break; 72 73 } 74 75 } 76 77 }
addDirectory是遞歸的常規的足跡橫貫當前目錄和子目錄。在這個例子中,這棵樹大小是有限的四目錄水平,從而節省時間。在實際應用中,參賽者應該改變的樹枝在只有當他們的擴展(見FlexGrid為WinForms教程)。
這個代碼創建了一個網格,看起來像這樣:
Creating Outlines and Trees with the C1FlexGrid Control(建立具有C1FlexGrid控制要點和樹木)
功能描述:一個獨特的和最受歡迎C1FlexGrid控制的特點就是能夠添加層次分組常規的非結構化的數據。
要達到這個目標,亞文化的概念C1FlexGrid節點的行。節點行不含定期數據。相反,他們作為標題下,類似的數據的落在了一起,一模一樣的節點到普通的樹狀視圖控件。喜歡一個樹狀視圖控件的節點,節點行可以倒塌和擴大,隱藏或顯示它們所包含的數據。也喜歡節點到TreeView
一個獨特的和最受歡迎的特點C1FlexGrid控制所有的信息就在那里,但是很難看到的總銷售每一個國家或客戶。你可以使用C1FlexGrid的概述特點,國家(數據組級別0),然后由市在每個國家(一級),然后由客戶內部各城市(要求等級2)。這是同一網格以售后增加大綱:
這柵格顯示相同的信息作為前勢必相同的數據來源),但增加了每個節點樹下,包含的數據總結下方。節點可以倒塌,只顯示總結,或擴大到顯示細節。注意每個節點排可以展現了一個多總結欄(在這種情況下,總單位售出和總多)。
在這篇文章中,我們將送你的整個過程將一個規則的網格成一個更豐富的輪廓的格子。
加載數據輸入綱要網格是完全一樣的加載到一個規則的網格。如果你的數據來源可在設計階段,你可以用的v isuals tudio財產的窗口,把財產DataSource網格系統的數據網格不用寫代碼。
如果數據源是不對外開放的設計時間,你可以設置你的網格系統的財產DataSource代碼。數據綁定的代碼通常看起來像這樣:
1 public Form1() 2 3 { 4 5 InitializeComponent(); 6 7 8 9 // get data 10 11 var fields = @" 12 13 Country, 14 15 City, 16 17 SalesPerson, 18 19 Quantity, 20 21 ExtendedPrice"; 22 23 var sql = string.Format("SELECT {0} FROM Invoices ORDER BY {0}", fields); 24 25 var da = new OleDbDataAdapter(sql, GetConnectionString()); 26 27 da.Fill(_dt); 28 29 30 31 // bind grid to data 32 33 this._flex.DataSource = _dt; 34 35 36 37 // format ExtendedPrice column 38 39 _flex.Cols["ExtendedPrice"].Format = "n2"; 40 41 }
代碼使用一個OleDbDataAdapter填補一個DataTable與數據,thenand然后指定DataTable到網格系統的DataSource財產。
運作后這些代碼,你將得到”規則格子“第一個圖像中所示。將這個規則的網格的網格所顯示的輪廓第二形象,我們需要插入節點行組成的輪廓。
Creating Node Rows(創建節點行)
點行規則的行幾乎相同,除了以下幾點:
•節點行不是數據的約束。當網格綁定到數據源,每屆常行對應的數據源中的一個項目。節點的行不。相反,它們的存在組包含相似的數據規則的行。
•節點行可以折疊或展開。當一個節點行倒塌,所有的數據和子節點都被隱藏。如果是可見的輪廓樹,用戶可以折疊和展開節點使用鼠標或鍵盤。如果樹是不可見的輪廓,然后節點可以展開或折疊只能使用代碼。
要確定是否行是一個節點或沒有,你可以使用IsNode屬性:
1 var row = _flex.Rows[rowIndex]; 2 3 if (row.IsNode) 4 5 { 6 7 // row is a node 8 9 var node = row.Node; 10 11 DoSomethingWithTheNode(node); 12 13 } 14 15 else 16 17 { 18 19 // this row is not a node 20 21 }
節點行可以創建在三個方面:
1。使用Rows.InsertNode方法。這將插入一個新節點指定索引列。一旦節點行已被創建,您可以使用像使用任何其他的行它(為每個列的數據,應用樣式等)。這是'低層次'插入總數和建築輪廓的方法。它使大多數控制和靈活性,表現如下。
2。使用C1FlexGrid.Subtotal方法。這種方法掃描整個網格,並自動插入節點在位置與可選的分類匯總行,其中電網數據的變化。這是'高層次'插入總數和建築輪廓的方法。它需要非常少的代碼,但這樣一些數據是如何在賽場上和結構是什么樣子大綱應假設。
3。如果格不作承諾,那么你可以打開屬性設置為true IsNode行成節點規則的行。請注意,僅當網格綁定。試圖把裝訂成一排普通節點的數據將導致網格拋出一個異常。
下面說明如何可以實現一個GroupBy方法,插入節點的行分組對一個給定列相同的值的代碼。
•節點行可以折疊或展開。當一個節點行倒塌,所有的數據和子節點都被隱藏。如果是可見的輪廓樹,用戶可以折疊和展開節點使用鼠標或鍵盤。如果樹是不可見的輪廓,然后節點可以展開或折疊只能使用代碼。
要確定是否行是一個節點或沒有,你可以使用IsNode屬性:
1 // group on a given column inserting nodes of a given level 2 3 void GroupBy(string columnName, int level) 4 5 { 6 7 object current = null; 8 9 for (int r = _flex.Rows.Fixed; r < _flex.Rows.Count; r++) 10 11 { 12 13 if (!_flex.Rows[r].IsNode) 14 15 { 16 17 var value = _flex[r, columnName]; 18 19 if (!object.Equals(value, current)) 20 21 { 22 23 // value changed: insert node 24 25 _flex.Rows.InsertNode(r, level); 26 27 28 29 // show group name in first scrollable column 30 31 _flex[r, _flex.Cols.Fixed] = value; 32 33 34 35 // update current value 36 37 current = value; 38 39 } 40 41 } 42 43 } 44 45 }
該代碼掃描所有列,跳過現有的節點行(所以它可以被調用時,添加不同層次的節點),並保持該列被分組對當前值的軌道。當電流值的變化,一個節點插入一行滾動顯示在第一列中的新組的名稱。
回到我們的例子,你可以使用此方法來創建調用兩個級別的大綱:
1 void _btnGroupCountryCity_Click(object sender, EventArgs e) 2 3 { 4 5 GroupBy("Country", 0); 6 7 GroupBy("City", 1); 8 9 }
很簡單,但也有一些注意事項。首先,該方法假定數據進行排序按大綱結構。在這個例子中,如果數據是按銷售人員,而不是按國別排序,綱要將有幾個0級,每個國家,這可能是不是你想要的節點。
此外,GroupBy方法可能會插入行,這將導致閃爍的網格。為了避免這種情況,你通常會設置的更新,然后才作出虛假重繪財產,並將其設置回True時完成。
為了處理這些問題,代碼創建大綱應重新編寫如下:
1 void _btnGroupCountryCity_Click(object sender, EventArgs e) 2 3 { 4 5 // suspend redrawing while updating 6 7 using (new DeferRefresh(_flex)) 8 9 { 10 11 // restore original sort (by Country, City, etc.) 12 13 ResetBinding(); 14 15 16 17 // group by Country, City 18 19 GroupBy("Country", 0); 20 21 GroupBy("City", 1); 22 23 } 24 25 }
該DeferRefresh類是一個簡單的工具,設置網格的重繪屬性為false,恢復其原始值時,處置。這確保了重繪,即使是恢復正常的更新過程中發生異常。這里是DeferRefresh類的實現:
1 /// Utility class used to encapsulate grid lengthy operations in a Redraw block. 2 3 /// This avoids flicker and ensures the Redraw property is reset properly in case 4 5 /// an exception is thrown during the operation. 6 7 class DeferRefresh : IDisposable 8 9 { 10 11 C1FlexGrid _grid; 12 13 bool _redraw; 14 15 public DeferRefresh(C1FlexGrid grid) 16 17 { 18 19 _grid = grid; 20 21 _redraw = grid.Redraw; 22 23 grid.Redraw = false; 24 25 } 26 27 public void Dispose() 28 29 { 30 31 _grid.Redraw = _redraw; 32 33 } 34 35 }
該BindGrid方法確保電網是我們的大綱結構中規定的次序排序。在我們的例子中,排序順序是由國家,城市,和銷售人員。代碼看起來是這樣的:
1 // unbind and re-bind grid in order to reset everything 2 3 void ResetBinding() 4 5 { 6 7 // unbind grid 8 9 _flex.DataSource = null; 10 11 12 13 // reset any custom sorting 14 15 _dt.DefaultView.Sort = string.Empty; 16 17 18 19 // re-bind grid 20 21 _flex.DataSource = _dt; 22 23 24 25 // format ExtendedPrice column 26 27 _flex.Cols["ExtendedPrice"].Format = "n2"; 28 29 30 31 // auto-size the columns to fit their content 32 33 _flex.AutoSizeCols(); 34 35 }
如果您運行此代碼現在,你會發現創建為節點行預期,但輪廓樹是不可見的,所以你不能展開和折疊節點。大綱樹中的關鍵部分。
Outline Tree(大綱樹)
功能描述:大綱樹是非常相似的一個你在一個TreeView控件經常看到的。它顯示了一個折疊/展開圖標旁邊,使用戶在每個節點行可以展開和折疊大綱看到所需級別縮進的詳細結構。
大綱樹可以顯示在屬性定義的Tree.Column任何列。默認情況下,這個屬性被設置為-1,這將導致在所有不被顯示的樹。要顯示在上面,你可以使用此代碼所舉的例子大綱樹:
代碼示例:
1 void _btnTreeCountryCity_Click(object sender, EventArgs e) 2 3 { 4 5 using (new DeferRefresh(_flex)) 6 7 { 8 9 // group by country and city as before 10 11 _btnGroupCountryCity_Click(this, EventArgs.Empty); 12 13 14 15 // show outline tree 16 17 _flex.Tree.Column = 0; 18 19 20 21 // autosize to accommodate tree 22 23 _flex.AutoSizeCol(_flex.Tree.Column); 24 25 26 27 // collapse detail nodes 28 29 _flex.Tree.Show(1); 30 31 } 32 33 }
該代碼調用以前的方法來建立大綱,thenand然后設置Tree.Column屬性設置為零,以顯示在第一列提綱樹。它還調用C1FlexGrid.AutoSizeCol方法,以確保該列的寬度足以容納大綱樹。最后,它調用Tree.Show方法來顯示所有0級節點(在這種情況下市),隱藏所有的細節。
樹屬性返回一個引用到GridTree對象,公開的幾種方法,並用於自定義大綱樹屬性。主要的有如下:
•列:獲取或設置列包含大綱樹索引。將此屬性設置為-1原因大綱樹將隱藏在用戶。
•縮進:獲取或設置縮進像素,相鄰節點之間的水平。水平較高的縮進導致樹變寬。
•風格:獲取或設置樹類型的大綱顯示。使用這個屬性來判斷是否應包括在樹的頂部按鈕欄,使用戶能夠折疊/展開整個樹,行是否和/或符號應顯示,以及是否應顯示連接線的數據行的樹以及節點行。
•LineColor:獲取或設置樹的連接線的顏色。
•的LineStyle:獲取或設置樹的連接線的樣式。
例如,通過改變上面的代碼包含以下兩行:
1 // show outline tree 2 3 _flex.Tree.Column = 0; 4 5 _flex.Tree.Style = TreeStyleFlags.CompleteLeaf; 6 7 _flex.Tree.LineColor = Color.White; 8 9 _flex.Tree.Indent = 30;
請注意按鈕標記為“1”,“2”,和“*”的左上角單元格。點擊這些按鈕會導致整個樹折疊或展開相應的水平。還要注意更廣泛的壓痕線和連接樹(“安妮Dodsworth的”)以及節點行定期行。
Adding Subtotals(添加分類別匯總)
功能描述:到目前為止,我們已經覆蓋了節點樹行和大綱創作。為了使真正有用的輪廓,但是,節點行應包括摘要它們包含的數據信息。
如果您創建一個輪廓樹使用C1FlexGrid.Subtotal方法,然后分類匯總會自動添加。這將在后面的章節所述。
如果你創建輪廓樹使用Rows.InsertNode方法如上所述,那么你應該直接使用到節點行的C1FlexGrid.Aggregate方法來計算每一組行並插入結果的匯總。
該C1FlexGrid.Subtotal方法列示上市如何做到這一點:
1 // add subtotals to each node at a given level 2 3 void AddSubtotals(int level, string colName) 4 5 { 6 7 // get column we are going to total on 8 9 int colIndex = _flex.Cols.IndexOf(colName); 10 11 12 13 // scan rows looking for nodes at the right level 14 15 for (int r = _flex.Rows.Fixed; r < _flex.Rows.Count; r++) 16 17 { 18 19 if (_flex.Rows[r].IsNode) 20 21 { 22 23 var node = _flex.Rows[r].Node; 24 25 if (node.Level == level) 26 27 { 28 29 // found a node, calculate the sum of extended price 30 31 var range = node.GetCellRange(); 32 33 var sum = _flex.Aggregate(AggregateEnum.Sum, 34 35 range.r1, colIndex, range.r2, colIndex, 36 37 AggregateFlags.ExcludeNodes); 38 39 40 41 // show the sum on the grid 42 43 // (will use the column format automatically) 44 45 _flex[r, colIndex] = sum; 46 47 } 48 49 } 50 51 } 52 53 }
該AddSubtotals方法掃描為節點的網格行的行尋找。當所期望的水平節點行被發現,該方法使用GetCellRange方法檢索節點的子行。然后,它使用C1FlexGrid.Aggregate方法來計算在整個范圍內對目標列中的值的總和。對總呼叫包括ExcludeNodes標志,以避免重復計算,現有節點。一旦經過計算小計,它被分配到節點行的細胞通常_flex [行,列]索引。
請注意,這並不會影響以任何方式的數據源,因為節點行不綁定到數據。
還要注意,該方法可以用來添加到每個節點的多個總計行。在這個例子中,我們將增加的數量和擴展價格列總數。除了金錢,你可以添加如平均,最高,最低等其他聚合
現在,我們可以使用此方法來創建節點行,輪廓樹,一個完整的輪廓和小計:
1 void _btnTreeCountryCity_Click(object sender, EventArgs e) 2 3 { 4 5 using (new DeferRefresh(_flex)) 6 7 { 8 9 // restore original sort (by Country, City, SalesPerson) 10 11 ResetBinding(); 12 13 14 15 // group by Country, City 16 17 GroupBy("Country", 0); // group by country (level 0) 18 19 GroupBy("City", 1); // group by city (level 1) 20 21 22 23 // add totals per Country, City 24 25 AddSubtotals(0, "ExtendedPrice"); // extended price per country (level 0) 26 27 AddSubtotals(0, "Quantity"); // quantity per country (level 0) 28 29 AddSubtotals(1, "ExtendedPrice"); // extended price per city (level 1) 30 31 AddSubtotals(1, "Quantity"); // quantity per city (level 1) 32 33 34 35 // show outline tree 36 37 _flex.Tree.Column = 0; 38 39 _flex.AutoSizeCol(_flex.Tree.Column); 40 41 _flex.Tree.Show(1); 42 43 } 44 45 }
如果您運行該項目現在,你會看到一個與該節目的總數量和每個國家和城市節點銷售金額排樹。這是非常好的,但有一個小問題。如果展開的節點任何行,你會看到許多重復的值。根據給定的城市節點的所有行具有相同的國家和城市:
這是正確的,但它也是一個屏幕房地產的浪費。消除這些重復的值很容易,你需要做的就是設置正在分組到零列的寬度。當你這樣做,但是,你要記得設置網格的AllowMerging屬性節點,因此分配給該節點行的文本將波及到可見列。 (另一個選擇是將文本的節點分配到第一個可見列,但合並通常是更好的解決方案,因為它可以讓你用更長的時間節點行文本)。
下面是修改后的代碼和最后的結果:
1 void _btnTreeCountryCity_Click(object sender, EventArgs e) 2 3 { 4 5 using (new DeferRefresh(_flex)) 6 7 { 8 9 // restore original sort (by Country, City, SalesPerson) 10 11 ResetBinding(); 12 13 14 15 // group by Country, City 16 17 GroupBy("Country", 0); // group by country (level 0) 18 19 GroupBy("City", 1); // group by city (level 1) 20 21 22 23 // hide columns that we grouped on 24 25 // (they only have duplicate values which already appear on the tree nodes) 26 27 // (but don't make them invisible, that would also hide the node text) 28 29 _flex.Cols["Country"].Width = 0; 30 31 _flex.Cols["City"].Width = 0; 32 33 34 35 // allow node content to spill onto next cell 36 37 _flex.AllowMerging = AllowMergingEnum.Nodes; 38 39 40 41 // add totals per Country, City 42 43 AddTotals(0, "ExtendedPrice"); // extended price per country (level 0) 44 45 AddTotals(0, "Quantity"); // quantity per country (level 0) 46 47 AddTotals(1, "ExtendedPrice"); // extended price per city (level 1) 48 49 AddTotals(1, "Quantity"); // quantity per city (level 1) 50 51 52 53 // show outline tree 54 55 _flex.Tree.Column = 0; 56 57 _flex.AutoSizeCol(_flex.Tree.Column); 58 59 _flex.Tree.Show(1); 60 61 } 62 63 }
Using the Subtotal Method(使用小計法)
功能描述:我們提到過,你也可以使用C1FlexGrid創建樹的C1FlexGrid.Subtotal方法。 TheSubtotal方法執行的GroupBy和AddSubtotals方法上述相同的任務,除非它在一個單一的步驟,因此這兩種東西多一點效率。
下面顯示了如何使用分類匯總方法的代碼來完成相同的事情,我們過了,只是快一點,沒有使用任何輔助方法做的:
1 void _btnTreeCountryCity_Click(object sender, EventArgs e) 2 3 { 4 5 using (new DeferRefresh(_flex)) 6 7 { 8 9 // restore original sort (by Country, City, SalesPerson) 10 11 ResetBinding(); 12 13 14 15 // group and total by country and city 16 17 _flex.Subtotal(AggregateEnum.Sum, 0, "Country", "ExtendedPrice"); 18 19 _flex.Subtotal(AggregateEnum.Sum, 0, "Country", "Quantity"); 20 21 _flex.Subtotal(AggregateEnum.Sum, 1, "City", "ExtendedPrice"); 22 23 _flex.Subtotal(AggregateEnum.Sum, 1, "City", "Quantity"); 24 25 26 27 // hide columns that we grouped on 28 29 // (they only have duplicate values which already appear on the tree nodes) 30 31 // (but don't make them invisible, that would also hide the node text) 32 33 _flex.Cols["Country"].Width = 0; 34 35 _flex.Cols["City"].Width = 0; 36 37 _flex.AllowMerging = AllowMergingEnum.Nodes; 38 39 40 41 // show outline tree 42 43 _flex.Tree.Column = 0; 44 45 _flex.AutoSizeCol(_flex.Tree.Column); 46 47 _flex.Tree.Show(1); 48 49 } 50 51 }
分類匯總的方法是非常方便和靈活。它有一個重載允許您指定的列進行分組並總計由索引或名稱,是否包含列標題的節點中插入的是,如何進行分組和數量等。下面摘要介紹了重載版本:
1。小計(AggregateEnum aggType)
這個版本的方法只需要一個聚合類型作為參數。它是有用的,只有去除,然后再插入新的現有的分類匯總。在這種情況下,aggType參數設置為AggregateEnum.Clear。
2。小計(AggregateEnum aggType,詮釋groupBy,詮釋totalOn)
小計(AggregateEnum aggType,字符串groupBy,字符串totalOn)
這些是最常用的重載。該參數是要插入的聚合類型和對本集團的總列上。被引用的列可以通過索引或名稱。后者是一個我們在上面的例子使用。
3。小計(AggregateEnum aggType,詮釋groupBy,詮釋totalOn,字符串標題)
小計(AggregateEnum aggType,字符串groupBy,字符串totalOn,串標題)
這些重載標題添加一個額外的參數。標題參數確定被添加到新節點的行被分組確定價值的文本。默認情況下,該值被分為上顯示出來,所以如果你是按國家分組時,節點的行會顯示“阿根廷”,“巴西”,等等。如果您設置標題參數為字符串,如“國家:{0}”,則節點的行會顯示“國家:阿根廷”代替。
4。小計(AggregateEnum aggType,詮釋groupFrom,詮釋groupTo,詮釋totalOn,字符串標題)
小計(AggregateEnum aggType,字符串groupFrom,字符串groupTo,字符串totalOn,串標題)
這些重載groupBy分成兩個參數:groupFrom和groupTo。默認情況下,小計方法插入一個節點,只要行的groupBy或前一列的值更改。
例如,如果你行已在“城市”為前行的列值相同,但是在“國家”一欄,不同的值,然后分類匯總方法假設行應在不同的組,並插入一個新節點即使排在groupBy列的值是相同的。這些總量讓你重寫該行為,並指定時,應考慮確定一個組列的范圍。
Using the Node class(使用節點類)
功能描述:Node類提供的方法和可用於創建和管理大綱樹屬性。這些方法和屬性很多是基於標准的TreeView的對象模型,因此他們應該最熟悉的開發人員。
要獲得一個節點對象,你可以:
使用該方法的返回值Rows.InsertNode:
var node = _flex.Rows.InsertNode(index, level);
或者你可以為現有的檢索使用行的節點屬性行節點:
var node = _flex.Rows[index].IsNode
? _flex.Rows[index].Node
: null;
無論哪種方式,一旦你有一個節點對象,你可以對其進行操作使用下列屬性和方法:
•等級:獲取或設置在樹節點級別的大綱。
•數據:獲取或設置由Node.Row和Tree.Column定義的單元格的值。
•圖像:獲取或設置由Node.Row和Tree.Column定義的細胞圖像。
•選中:獲取或設置由Node.Row和Tree.Column定義的細胞檢查狀態。
•折疊/展開:獲取或設置節點的折疊/展開狀態。
您還可以探索大綱結構使用以下方法:
•GetCellRange():獲取一個CellRange對象,描述了屬於此列節點范圍。
•兒童:獲取此節點下的子節點的數目。
•節點:節點陣列獲取一個包含此節點的子節點。
•GetNode:獲取節點,有一個給定的關系到該節點(父,第一個孩子,一個兄弟,等)。
上述討論的約束情況下,這里的電網是連接到數據源,提供了數據集中。您還可以創建未綁定的情況下樹木和輪廓。其實有些事情是在這種情況下更簡單,因為你可以變成一個節點行通過設置IsNode屬性為true任何行。
如果格不作承諾,它擁有所有顯示的數據,你做的事情是不可能的,當一個數據源擁有數據。例如,你可以移動使用移動方法,通過與C1FlexGrid提供TreeNode的樣本顯示樹節點。
使用未綁定的網格節點非常相似,在常規使用TreeView控件的節點。