摘自: http://3y.uu456.com/bp-e2746s16s2d380eb62946d27-1.html

C#;c1FlexGrid帮助文档;Value-MappedLists(值映射列表;功能描述:上述财产的ComboList确保单元格;网格,完全一样,如果用户已输入的值;功能示例:System.Collections.;实现IDictionary的任何类可以作为一个D;//KeepsAddorder.System.C;ld.Add(2,"Two

下载:C#++c1FlexGrid+帮助文档0.Doc

 

C#

c1FlexGrid 帮助文档

Value-Mapped Lists(值映射列表 值映射列表) 值映射列表

功能描述:上述财产的 ComboList 确保单元格的值是从名单中挑选。由用户选择的值转换成列的适当类型和存储在

网格,完全一样,如果用户已输入的值。 在许多情况下,细胞能够承担来自明确列出的值,但是你想显示一个用户的实际价值的版本。例如,如果一个列包含的 产品代码,您可能要存储的代码,但显示的产品名称来代替。 这是通过的 DataMap 财产。此属性包含一个引用到的 IDictionary 对象之间建立什么是存储在网格中,什么是可见的用 户(IDictionary 接口是 System.Collections 命名空间中定义,并得到其他 Hashtable 类中实现)映射。 例如,下面的代码创建了一个数据映射,它包含颜色值,他们的名字。这些颜色都存储在网格中,他们的名字所显示的 用户:

功能示例: System.Collections.Hashtable dtMap = new System.Collections.Hashtable(); dtMap.Add(Color.Red, "Apple"); dtMap.Add(Color.Green, "Forest"); dtMap.Add(Color.Blue, "Sky"); dtMap.Add(Color.Black, "Coal"); dtMap.Add(Color.White, "Snow"); _flex.Cols[].DataType = typeof(Color); _flex.Cols[].DataMap = dtMap;

实现 IDictionary 的任何类可以作为一个 DataMap 使用。例如,哈希表,ListDictionary 的,和 SortedList 都提供了有效 的数据地图。所不同的是,当他们在编辑栏使用时,在下拉列表中项目的顺序将取决于类。 各种各样的 SortedList 类的重点项目,Hashtable 的使用任意命令,ListDictionary 的保持在哪些项目被添加到列表的顺 序。正因为如此,ListDictionary 的通常是为 DataMaps 的最佳选择。 请注意,在数据映射的键必须为同一类型的细胞被编辑。例如,如果一个列包含短整数(Int16 的),那么任何数据列 关联应该有短整数键地图。作为密钥不会正常工作整数(Int32 的)。 下面的例子显示的区别: private void Form1_Load(object sender, System.EventArgs e); { // Sorts by key. System.Collections.SortedList sl = new System.Collections.SortedList(); sl.Add("0", "Zero"); sl.Add("1", "One"); sl.Add("2", "Two"); sl.Add("3", "Three");

// Keeps Add order. System.Collections.Specialized.ListDictionary ld = new System.Collections.Specialized.ListDictionary(); ld.Add(0, "Zero"); ld.Add(1, "One");

ld.Add(, "Two"); ld.Add(, "Three");

// Arbitrary order. System.Collections.Hashtable ht = new System.Collections.Hashtable(); ht.Add(0, "Zero"); ht.Add(1, "One"); ht.Add(2, "Two"); ht.Add(3, "Three");

_flex.Cols[].DataMap = sl; _flex.Cols[].Caption = "SortedList"; _flex.Cols[].DataMap = ld; _flex.Cols[].Caption = "ListDictionary"; _flex.Cols[].DataMap = ht; _flex.Cols[].Caption = "HashTable"; }

Cell Buttons (细胞按钮 细胞按钮) 细胞按钮

功能描述:某些类型的细胞,可能需要较复杂的编辑

文本框或下拉列表等。例如,如果一个列包含文件名称或一种颜色, 它应该是一个对话框编辑。 在这种情况下, 你应该设置 ComboList 属性省略号“...”。 ( )该控件将显示一个按钮, 旁边的单元格, 将触发 CellButtonClick 事件当用户点击就可以了。您可以捕获的事件,显示该对话框,并更新用户的选择单元格的内容。 如果您添加一个省略号前管道字符,那么用户将被允许进入细胞编辑输入单元格内容。 默认情况下,细胞按钮显示省略号。您可以指定图片的单元格按钮使用 CellButtonImage 财产。 下面演示了如何使用手机的按钮显示选择列中的某个颜色的颜色选择器对话框的例子。

功能示例: 
// Set up color column.
Column c = _flex.Cols[1]; c.DataType = typeof(Color); // Show cell button.
c.ComboList = "..."; 此代码设置列,以便用户可以点击一个按钮,然后从对话框中的颜色。下一步是处理的代码单元格按钮上点击: private void _flex_CellButtonClick( object sender, RowColEventArgs e) {
  // Create color picker dialog.
  ColorDialog clrDlg = new ColorDialog();   // Initialize the dialog.
  if (_flex[e.Row, e.Col] == typeof(Color)) { clrDlg.Color = (Color)_flex[e.Row, e.Col]; }   // Get new color from dialog and assign it to the cell.
  if (clrDlg.ShowDialog() == DialogResult.OK) { _flex[e.Row, e.Col] = clrDlg.Color; }
} Masks(面具) (面具) 该 C1FlexGrid 控件还支持蒙面编辑。使用这种类型的编辑输入掩码提供一个模板,并自动验证用户类型作为输入。面 具是指定的 EditMask 属性,可以用正则文本字段和下拉式组合领域。 面膜字符串有两种类型的字符:字面字符,成为输入部分和模板字符,这为属于特定类别中的字符为占位符(例如,数 字或字母)。例如,下面的代码指定一个“()-”,以第一列,它包含电话号码的编辑掩码(数字“” 是一个占位符,对于任何数字的缩写): 代码示例: // Set up a phone number edit mask. _flex.Cols[1].EditMask = "(999) 999-9999"; EditMask 属性设置为一个非空字符串会导致它使用内置的蒙面编辑器,即使该列包含日期/时间值(通常,一个 DateTimePicker 控件用于编辑这些列)。这是特别方便,如果您有 DateTime 列持有时间(无日期)。在这种情况下, 可以设置以下属性,以使用,而不是在 DateTimePicker 控制蒙面编辑: _flex.Cols[].DataType = typeof(DateTime); _flex.Cols[].Format = "hh:mm tt"; _flex.Cols[].EditMask = "99:99 LL"; 对话框中输入掩码可以通过菜单或任务列通过 C1FlexGrid 列编辑器。 在任务菜单?列,单击编辑掩码框中的省略号按钮。 ?在 C1FlexGrid 栏编辑器,找到在左窗格中的 EditMask 属性,单击省略号按钮旁边。 注意:在输入掩码列的特定对话框 ,只会改变所选列 EditMask 属性。 有关用来建立遮罩字串语法的详细信息,请参阅参考部分 EditMask 控制的财产。 如果在同一列中不同的细胞需要不同的面具,捕获 BeforeEdit 事件,并设置 EditMask 属性为当前单元格适当的值。 Validation(验证) (验证) 功能描述:在许多情况下,编辑口罩本身是不够的,以确保用户输入的数据是有效的。例如,一个面具不会让你指定一 个可能值的范围,或验证当前单元格在另一个单元格的内容为基础。 在这种情况下,捕获 ValidateEdit 事件,看看在 Editor.Text 属性中包含的值是当前单元格有效的项目(在这一点上,细 胞仍然在它的原始值)。如果输入是无效的,取消参数设置为 true,将继续留在格编辑,直到用户输入一个有效的输入 模式。 例如,下面的代码验证成货币列输入,以确保输入的值在 和 是: 代码示例: private void _flex_ValidateEdit( object sender, ValidateEditEventArgs e) { // Validate amounts. if (_flex.Cols[e.Col].DataType == typeof(Decimal)) { try { Decimal dec = Decimal.Parse(_flex.Editor.Text); if ( dec < 1000 || dec > 10000 ) { MessageBox.Show("Value must be between 1,000 and 10,000"); e.Cancel = true; } } catch { MessageBox.Show("Value not recognized as a Currency"); e.Cancel = true; } } } Merged Table Headers(合并表头) (合并表头) 功能描述:要创建合并表头,你必须首先设置网格的 AllowMerging 属性 FixedOnly。然后,指定的行和列要合并设 置的行和列的 AllowMerging 属性。最后,分配到页眉文本细胞,使细胞要合并有相同的内容。 下面的代码显示了一个例子: 代码示例: private void Form1_Load(System.object sender, System.EventArgs e) { int i; // Initialize the control. _flex.Styles.Normal.WordWrap = true; _flex.Cols.Count = 9; _flex.Rows.Fixed = 2; _flex.AllowMerging = C1.Win.C1FlexGrid.AllowMergingEnum.FixedOnly; // Create row headers. _flex.Rows[0].AllowMerging = true; // Merge the four cells with same contents. C1.Win.C1FlexGrid.CellRange rng = _flex.GetCellRange(0, 1, 0, 4); rng.Data = "North"; // Merge the four cells with same contents. rng = _flex.GetCellRange(0, 5, 0, 8); rng.Data = "South"; for ( i = 1 ; i <= 4; i++) { _flex[1, i] = "Qtr " + i; _flex[1, i + 4] = "Qtr " + i; } // Create the column header. _flex.Cols[0].AllowMerging = true; // Merge the two cells with same contents. rng = _flex.GetCellRange(0, 0, 1, 0); rng.Data = "Sales by Product"; // Align and autosize the cells. _flex.Styles.Fixed.TextAlign = C1.Win.C1FlexGrid.TextAlignEnum.CenterCenter; _flex.AutoSizeCols(1, _flex.Cols.Count - 1, 10); } This is the result: Merged Data Views(合并数据) (合并数据) 功能描述: 单元格合并的工作方式相同,当网格绑定到数据源。下面的代码显示了绑定到数据源在设计时一格一个例子 。如需绑定 到数据源的信息,请参见绑定到数据源。 代码示例: private void Form1_Load( System.object sender, { int i; System.EventArgs e) // Set up cell merging. _flex.AllowMerging = C1.Win.C1FlexGrid.AllowMergingEnum.RestrictCols; for (int i = _flex.Cols.Fixed; i <= _flex.Cols.Count - 1; i++) { _flex.Cols(i).AllowMerging = true; } } This is the result: Creating Subtotals(创建分类汇总) (创建分类汇总) 功能描述:该 C1FlexGrid.Subtotal 方法将包含在常规(非小计)行的汇总数据汇总行。 小计支援阶层集合体。例如,如果你的网格包含销售数据,您可能获得总销售额合计按产品,区域,和销售人员的数字。 下面的代码说明了这一点 代码示例: private void ShowTotals() { // Show OutlineBar on column 0. _flex.Tree.Column = 0; _flex.Tree.Style = TreeStyleFlags.Simple; // Clear existing subtotals. _flex.Subtotal(AggregateEnum.Clear); // Get a Grand total (use -1 instead of column index). _flex.Subtotal(AggregateEnum.Sum, -1, -1, 3, "Grand Total"); // Total per Product (column 0). _flex.Subtotal(AggregateEnum.Sum, 0, 0, 3, "Total {0}"); // Total per Region (column 1). _flex.Subtotal(AggregateEnum.Sum, 1, 1, 3, "Total {0}"); // Size column widths based on content. _flex.AutoSizeCols(); } 当 C1FlexGrid.Subtotal 方法添加行的汇总信息,它会自动分配小计样式新行(有内置的 个分类汇总级别样式) 。您可 以通过更改在与风格编辑器或代码设计师的大纲样式属性的分类汇总行的外观。例如: // Set styles for subtotals. CellStyle cs; cs = _flex.Styles[CellStyleEnum.GrandTotal]; cs.BackColor = Color.Black; cs.ForeColor = Color.White; cs.Font = new Font(Font, FontStyle.Bold); cs = _flex.Styles[CellStyleEnum.Subtotal0]; cs.BackColor = Color.DarkRed; cs.ForeColor = Color.White; cs.Font = new Font(Font, FontStyle.Bold); cs = _flex.Styles[CellStyleEnum.Subtotal1]; cs.BackColor = Color.DarkBlue; cs.ForeColor = Color.White; After executing this code, the grid would look like this: 在总计行中包含的所有产品,地区和销售人员的总销售额。它是一个用在方法调用的 C1FlexGrid.Subtotal groupOn 参 数为-。另按产品分类汇总显示和地区的总销售额。他们创建的一个值 ,为 groupOn 参数 。 您也可以计算总量比其他款项(例如,平均值或百分比) ,并计算每行数总量(例如,毛保费及净销售额) 。 由小计小计行方法建立在三个方面有所不同规则的行: 。小计行可以被自动删除通过调用参数与 flexSTClear 小计方法。这是非常有用的数据提供,用户可以移动列,并重新 对数据进行排序,因此有必要重新计算分类汇总的动态视图。 。小计行可作为节点的一个大纲,让您折叠和展开的行群体提出一个数据概述或透露其细节。要看到树的轮廓,你需 要设置列和 Tree.Style 属 性来定义的位置和轮廓树的外观。 。小计行可以被视为在一个树节点。你可以通过任何节点属性分类汇总行中的节点对象。 。当网格绑定到数据源,小计行不符合实际的数据。如果你在数据源中的光标,次全行会被忽略在网格中。 大纲树允许用户通过折叠和展开的节点上点击网格的部分。您可以使用大纲树来显示多种类型的信息,不仅总量。下一 个主题演示如何创建一个自定义大纲树来显示目录信息。 Creating Custom Trees(创建自定义树) (创建自定义树) 功能描述:创造轮廓树不使用小结的方法中,你需要遵循这些步骤: 。添加排电网。 。把一些行转换成轮廓节点 IsNode 把他们的财产是真实的。 。得到节点对象为每个节点排并设置其水平产权界定节点的位置在树上的层次结构。更高的价值意味着节点是更 深的(更)为轮廓缩进树。 例如,下面的代码创建一个目录树: 代码示例: // add these using statements at the top of the form using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.IO; using C1.Win.C1FlexGrid; private void Form1_Load(object sender, EventArgs e) { // Initialize grid layout. _flex.Cols.Fixed = 0; _flex.Cols.Count = 1; _flex.Rows.Count = 1; _flex.ExtendLastCol = true; _flex.Styles.Normal.TextAlign = TextAlignEnum.LeftCenter; _flex.Styles.Normal.Border.Style = BorderStyleEnum.None; // Initialize outline tree. _flex.Tree.Column = 0; _flex.Tree.Style = TreeStyleFlags.SimpleLeaf; _flex.Tree.LineColor = Color.DarkBlue; // Populate the grid. AddDirectory(@"c:\\", 0); } 上面的代码初始化电网布局,并调用 AddDirectory 例程,并在网格的填充和设立树状结构的工作: private void AddDirectory(string dir, int level) { // add this directory string thisDir = Path.GetFileName(dir); if (thisDir.Length == 0) { thisDir = dir; } _flex.AddItem(thisDir); //make this new row a node Row row = _flex.Rows[_flex.Rows.Count - 1]; row.IsNode = true; //set node level Node nd = row.Node; nd.Level = level; // add files in this directory int cnt = 0; Row r; foreach (string file in Directory.GetFiles(dir)) { _flex.AddItem(Path.GetFileName(file).ToLower()); //mark the row without child row as node r = _flex.Rows[_flex.Rows.Count - 1]; r.IsNode = true; r.Node.Level = level + 1; cnt = cnt + 1; if (cnt > 10) break; } // add subdirectories (up to level 4) if (level <= 4) { cnt = 0; foreach (string subdir in Directory.GetDirectories(dir)) { AddDirectory(subdir, level + ); cnt = cnt + ; if (cnt > ) break; } } } addDirectory 是递归的常规的足迹横贯当前目录和子目录。在这个例子中,这棵树大小是有限的四目录水平,从而节省 时间。在实际应用中,参赛者应该改变的树枝在只有当他们的扩展(见 Flex
Grid为WinForms教程);这个代码创建了一个网格,看起来像这样:;CreatingOutlinesandTrees;功能描述:一个独特的和最受欢迎C1FlexGri;要达到这个目标,亚文化的概念C1FlexGri;一个独特的和最受欢迎的特点C1FlexGrid控;这栅格显示相同的信息作为前势必相同的数据来源),;在这篇文章中,我们将送你的整个过程将

下载:C#++c1FlexGrid+帮助文档0.Doc

 

Grid 为 WinForms 教程)。

这个代码创建了一个网格,看起来像这样:

Creating Outlines and Trees with the C1FlexGrid Control(建立具有 C1FlexGrid 建立具有 控制要点和树木) 控制要点和树木

功能描述:一个独特的和最受欢迎 C1FlexGrid 控制的特点就是能够添加层次分组常规的非结构化的数据。

要达到这个目标,亚文化的概念 C1FlexGrid 节点的行。节点行不含定期数据。相反,他们作为标题下,类似的数据的 落在了一起,一模一样的节点到普通的树状视图控件。喜欢一个树状视图控件的节点,节点行可以倒塌和扩大,隐藏或显示 它们所包含的数据。也喜欢节点到 TreeView

一个独特的和最受欢迎的特点 C1FlexGrid 控制所有的信息就在那里,但是很难看到的总销售每一个国家或客户。你可以 使用 C1FlexGrid 的概述特点,国家(数据组级别 ),然后由市在每个国家(一级),然后由客户内部各城市(要求等级 )。这是 同一网格以售后增加大纲:

这栅格显示相同的信息作为前势必相同的数据来源),但增加了每个节点树下,包含的数据总结下方。 节点可以倒塌,只显示 总结,或扩大到显示细节。注意每个节点排可以展现了一个多总结栏(在这种情况下,总单位售出和总多)。

在这篇文章中,我们将送你的整个过程将一个规则的网格成一个更丰富的轮廓的格子。

加载数据输入纲要网格是完全一样的加载到一个规则的网格。 如果你的数据来源可在设计阶 段,你可以用的 v isuals tudio 财产的窗口,把财产 DataSource 网格系统的数据网格不用写代码。 如果数据源是不对外开放的设计时间,你可以设置你的网格系统的财产 DataSource 代 码。数据绑定的代码通常看起来像这样:

public Form1() { InitializeComponent();

// get data var fields = @" Country, City, SalesPerson, Quantity, ExtendedPrice"; var sql = string.Format("SELECT {0} FROM Invoices ORDER BY {0}", fields); var da = new OleDbDataAdapter(sql, GetConnectionString()); da.Fill(_dt);

// bind grid to data this._flex.DataSource = _dt;

// format ExtendedPrice column _flex.Cols["ExtendedPrice"].Format = "n2"; }

代码使用一个 OleDbDataAdapter 填补一个 DataTable 与数据,thenand 然后指定 DataTable 到 网格系统的 DataSource 财产。

运作后这些代码,你将得到”规则格子“第一个图像中所示。将这个规则的网格的网格 所显示的轮廓第二形象,我们需要插入节点行组成的轮廓。

Creating Node Rows(创建节点行 创建节点行) 创建节点行

点行规则的行几乎相同,除了以下几点:

?节点行不是数据的约束。当网格绑定到数据源,每届常行对应的数据源中的一个项目。节点的行不。相反,它们的存在 组包含相似的数据规则的行。 ?节点行可以折叠或展开。当一个节点行倒塌,所有的

的数据和子节点都被隐藏。如果是可见的轮廓树,用户可以折叠和展 开节点使用鼠标或键盘。如果树是不可见的轮廓,然后节点可以展开或折叠只能使用代码。 要确定是否行是一个节点或没有,你可以使用 IsNode 属性:

var row = _flex.Rows[rowIndex]; if (row.IsNode) { // row is a node var node = row.Node; DoSomethingWithTheNode(node); } else { // this row is not a node

}

节点行可以创建在三个方面:

。使用 Rows.InsertNode 方法。这将插入一个新节点指定索引列。一旦节点行已被创建,您可以使用像使用任何其他 的行它(为每个列的数据,应用样式等) 。这是'低层次'插入总数和建筑轮廓的方法。它使大多数控制和灵活性,表现如 下。

。使用 C1FlexGrid.Subtotal 方法。这种方法扫描整个网格,并自动插入节点在位置与可选的分类汇总行,其中电网数 据的变化。这是'高层次'插入总数和建筑轮廓的方法。它需要非常少的代码,但这样一些数据是如何在赛场上和结构是什 么样子大纲应假设。

。如果格不作承诺,那么你可以打开属性设置为 true IsNode 行成节点规则的行。请注意,仅当网格绑定。试图把装订 成一排普通节点的数据将导致网格抛出一个异常。

下面说明如何可以实现一个 GroupBy 方法,插入节点的行分组对一个给定列相同的值的代码。

?节点行可以折叠或展开。当一个节点行倒塌,所有的数据和子节点都被隐藏。如果是可见的轮廓树,用户可以折叠和展 开节点使用鼠标或键盘。如果树是不可见的轮廓,然后节点可以展开或折叠只能使用代码。

要确定是否行是一个节点或没有,你可以使用 IsNode 属性:

// group on a given column inserting nodes of a given level void GroupBy(string columnName, int level) { object current = null; for (int r = _flex.Rows.Fixed; r < _flex.Rows.Count; r++) { if (!_flex.Rows[r].IsNode) { var value = _flex[r, columnName]; if (!object.Equals(value, current)) { // value changed: insert node _flex.Rows.InsertNode(r, level);

// show group name in first scrollable column _flex[r, _flex.Cols.Fixed] = value;

// update current value current = value; } }

} }

该代码扫描所有列,跳过现有的节点行(所以它可以被调用时,添加不同层次的节点) ,并保持该列被分组对当前值的 轨道。当电流值的变化,一个节点插入一行滚动显示在第一列中的新组的名称。

回到我们的例子,你可以使用此方法来创建调用两个级别的大纲:

void _btnGroupCountryCity_Click(object sender, EventArgs e) { GroupBy("Country", ); GroupBy("City", ); } 很简单,但也有一些注意事项。首先,该方法假定数据进行排序按大纲结构。在这个例子中,如果数据是按销售人员, 而不是按国别排序,纲要将有几个

级,每个国家,这可能是不是你想要的节点。

此外,GroupBy 方法可能会插入行,这将导致闪烁的网格。为了避免这种情况,你通常会设置的更新,然后才作出虚假 重绘财产,并将其设置回 True 时完成。

为了处理这些问题,代码创建大纲应重新编写如下: void _btnGroupCountryCity_Click(object sender, EventArgs e) { // suspend redrawing while updating using (new DeferRefresh(_flex)) { // restore original sort (by Country, City, etc.) ResetBinding();

// group by Country, City GroupBy("Country", 0); GroupBy("City", 1); } } 该 DeferRefresh 类是一个简单的工具,设置网格的重绘属性为 false,恢复其原始值时,处置。这确保了重绘,即使是 恢复正常的更新过程中发生异常。这里是 DeferRefresh 类的实现:

/// Utility class used to encapsulate grid lengthy operations in a Redraw block. /// This avoids flicker and ensures the Redraw property is reset properly in case /// an exception is thrown during the operation. class DeferRefresh : IDisposable { C1FlexGrid _grid; bool _redraw; public DeferRefresh(C1FlexGrid grid)

{ _grid = grid; _redraw = grid.Redraw; grid.Redraw = false; } public void Dispose() { _grid.Redraw = _redraw; } } 该 BindGrid 方法确保电网是我们的大纲结构中规定的次序排序。在我们的例子中,排序顺序是由国家,城市,和销售人 员。代码看起来是这样的:

// unbind and re-bind grid in order to reset everything void ResetBinding() { // unbind grid _flex.DataSource = null;

// reset any custom sorting _dt.DefaultView.Sort = string.Empty;

// re-bind grid _flex.DataSource = _dt;

// format ExtendedPrice column _flex.Cols["ExtendedPrice"].Format = "n2";

// auto-size the columns to fit their content _flex.AutoSizeCols(); } 如果您运行此代码现在,你会发现创建为节点行预期,但轮廓树是不可见的,所以你不能展开和折叠节点。大纲树中的 关键部分。

Outline Tree(大纲树 大纲树) 大纲树

功能描述:大纲树是非常相似的一个你在一个 TreeView 控件经常看到的。它显示了一个折叠/展开图标旁边,使用户在 每个节点行可以展开和折叠大纲看到所需级别缩进的详细结构。

大纲树可以显示在属性定义的 Tree.Column 任何列。 默认情况下, 这个属性被设置为-, 这将导致在所有不被显示的树。

要显示在上面,你可以使用此代码所举的例子大纲树:

代码示例:

void _btnTreeCountryCity_Click(object sender, EventArgs e) { using (new DeferRefresh(_flex)) { // group by country and city as before _btnGroupCountryCity_Click(this, EventArgs.Empty);

// show outline tree _flex.Tree.Column = 0;

// autosize to accommodate tree _flex.AutoSizeCol(_flex.Tree.Column);

// collapse detail nodes _flex.Tree.Show(1); } }

该代码调用以前的方法来建立大纲,thenand 然后设置 Tree.Column 属性设置为零,

以显示在第一列提纲树。它还调用 C1FlexGrid.AutoSizeCol 方法,以确保该列的宽度足以容纳大纲树。最后,它调用 Tree.Show 方法来显示所有  级节 点(在这种情况下市) ,隐藏所有的细节。

树属性返回一个引用到 GridTree 对象,公开的几种方法,并用于自定义大纲树属性。主要的有如下:

?列:获取或设置列包含大纲树索引。将此属性设置为- 原因大纲树将隐藏在用户。

?缩进:获取或设置缩进像素,相邻节点之间的水平。水平较高的缩进导致树变宽。

?风格:获取或设置树类型的大纲显示。使用这个属性来判断是否应包括在树的顶部按钮栏,使用户能够折叠/展开整个 树,行是否和/或符号应显示,以及是否应显示连接线的数据行的树以及节点行。

?LineColor:获取或设置树的连接线的颜色。

?的 LineStyle:获取或设置树的连接线的样式。

例如,通过改变上面的代码包含以下两行:

// show outline tree _flex.Tree.Column = 0; _flex.Tree.Style = TreeStyleFlags.CompleteLeaf;

_flex.Tree.LineColor = Color.White; _flex.Tree.Indent = ;

请注意按钮标记为“”,“”,和“*”的左上角单元格。点击这些按钮会导致整个树折叠或展开相应的水平。还要注意更广 泛的压痕线和连接树(“安妮 Dodsworth 的”)以及节点行定期行。

Adding Subtotals(添加分类别汇总) (添加分类别汇总)

功能描述:到目前为止,我们已经覆盖了节点树行和大纲创作。为了使真正有用的轮廓,但是,节点行应包括摘要

它们包含的数据信息。

如果您创建一个轮廓树使用 C1FlexGrid.Subtotal 方法,然后分类汇总会自动添加。这将在后面的章节所述。

如果你创建轮廓树使用 Rows.InsertNode 方法如上所述,那么你应该直接使用到节点行的 C1FlexGrid.Aggregate 方法 来计算每一组行并插入结果的汇总。

该 C1FlexGrid.Subtotal 方法列示上市如何做到这一点:

// add subtotals to each node at a given level void AddSubtotals(int level, string colName) { // get column we are going to total on int colIndex = _flex.Cols.IndexOf(colName);

// scan rows looking for nodes at the right level for (int r = _flex.Rows.Fixed; r < _flex.Rows.Count; r++) { if (_flex.Rows[r].IsNode) { var node = _flex.Rows[r].Node;

if (node.Level == level) { // found a node, calculate the sum of extended price var range = node.GetCellRange(); var sum = _flex.Aggregate(AggregateEnum.Sum, range.r1, colIndex, range.r2, colIndex, AggregateFlags.ExcludeNodes);

// show the sum on the grid // (will use the column format automatically) _flex[r, colIndex] = sum; } } } }

该 AddSubtotals 方法扫描为节点的网格行的行寻找。当所期望的水平节点行被发现,该方法使用 GetCellRange 方法检 索节点的子行。然后,它使用 C1FlexGrid.Aggrega

te 方法来计算在整个范围内对目标列中的值的总和。对总呼叫包括 ExcludeNodes 标志,以避免重复计算,现有节点。一旦经过计算小计,它被分配到节点行的细胞通常_flex [行,列]索 引。 请注意,这并不会影响以任何方式的数据源,因为节点行不绑定到数据。

还要注意,该方法可以用来添加到每个节点的多个总计行。在这个例子中,我们将增加的数量和扩展价格列总数。除了 金钱,你可以添加如平均,最高,最低等其他聚合

现在,我们可以使用此方法来创建节点行,轮廓树,一个完整的轮廓和小计:

void _btnTreeCountryCity_Click(object sender, EventArgs e) { using (new DeferRefresh(_flex)) { // restore original sort (by Country, City, SalesPerson) ResetBinding();

// group by Country, City GroupBy("Country", 0); // group by country (level 0) GroupBy("City", 1); // group by city (level 1)

// add totals per Country, City AddSubtotals(0, "ExtendedPrice"); AddSubtotals(0, "Quantity"); AddSubtotals(1, "ExtendedPrice"); AddSubtotals(1, "Quantity"); // extended price per country (level 0) // quantity per country (level 0) // extended price per city (level 1) // quantity per city (level 1)

// show outline tree _flex.Tree.Column = 0; _flex.AutoSizeCol(_flex.Tree.Column); _flex.Tree.Show(1); } }

如果您运行该项目现在,你会看到一个与该节目的总数量和每个国家和城市节点销售金额排树。这是非常好的,但有一 个小问题。如果展开的节点任何行,你会看到许多重复的值。根据给定的城市节点的所有行具有相同的国家和城市:

这是正确的,但它也是一个屏幕房地产的浪费。消除这些重复的值很容易,你需要做的就是设置正在分组到零列的宽度。 当你这样做,但是,你要记得设置网格的 AllowMerging 属性节点,因此分配给该节点行的文本将波及到可见列。 (另 一个选择是将文本的节点分配到第一个可见列,但合并通常是更好的解决方案,因为它可以让你用更长的时间节点行文 本) 。

下面是修改后的代码和最后的结果:

void _btnTreeCountryCity_Click(object sender, EventArgs e) { using (new DeferRefresh(_flex)) { // restore original sort (by Country, City, SalesPerson) ResetBinding();

// group by Country, City GroupBy("Country", 0); // group by country (level 0) GroupBy("City", 1); // group by city (level 1)

// hide columns that we grouped on

// (they only have duplicate values which already appear on the tree nodes) // (but don't make them invisible, that would also hide the node text) _flex.Cols["Country"].Width = 0; _flex.Cols["City"].Width = 0;

// allow node content to spill onto next cell _flex.AllowMerging = AllowMergingEnum.Nodes;

// add totals per Country, City AddTotals(0, "ExtendedPrice"); AddTotals(0, "Quantity"); AddTotals(1, "ExtendedPrice"); AddTotals(1, "Quantity"); /
extendedpricepercountry(;//showoutlinetree_flex.T;UsingtheSubtotalMethod(使;功能描述:我们提到过,你也可以使用C1FlexG;TheSubtotal方法执行的;GroupBy和AddSubtotals方法上述;下面显示了如何使用分类汇总方法的代码来完成相同;void_btnTreeC

 

extended price per country (level ) // quantity per country (level 0) // extended price per city (level 1) // quantity per city (level 1)

// show outline tree _flex.Tree.Column = 0; _flex.AutoSizeCol(_flex.Tree.Column); _flex.Tree.Show(1); } }

Using the Subtotal Method(使用小计法) (使用小计法)

功能描述:我们提到过,你也可以使用 C1FlexGrid 创建树的 C1FlexGrid.Subtotal 方法。

TheSubtotal 方法执行的

GroupBy 和 AddSubtotals 方法上述相同的任务,除非它在一个单一的步骤,因此这两种东西多一点效率。

下面显示了如何使用分类汇总方法的代码来完成相同的事情,我们过了,只是快一点,没有使用任何辅助方法做的:

void _btnTreeCountryCity_Click(object sender, EventArgs e) { using (new DeferRefresh(_flex)) { // restore original sort (by Country, City, SalesPerson) ResetBinding();

// group and total by country and city _flex.Subtotal(AggregateEnum.Sum, 0, "Country", "ExtendedPrice"); _flex.Subtotal(AggregateEnum.Sum, 0, "Country", "Quantity"); _flex.Subtotal(AggregateEnum.Sum, 1, "City", "ExtendedPrice"); _flex.Subtotal(AggregateEnum.Sum, 1, "City", "Quantity");

// hide columns that we grouped on // (they only have duplicate values which already appear on the tree nodes) // (but don't make them invisible, that would also hide the node text) _flex.Cols["Country"].Width = 0; _flex.Cols["City"].Width = 0; _flex.AllowMerging = AllowMergingEnum.Nodes;

// show outline tree _flex.Tree.Column = 0; _flex.AutoSizeCol(_flex.Tree.Column); _flex.Tree.Show(1); } } 分类汇总的方法是非常方便和灵活。它有一个重载允许您指定的列进行分组并总计由索引或名称,是否包含列标题的节 点中插入的是,如何进行分组和数量等。下面摘要介绍了重载版本:

。小计(AggregateEnum aggType)

这个版本的方法只需要一个聚合类型作为参数。它是有用的,只有去除,然后再插入新的现有的分类汇总。在这种情况 下,aggType 参数设置为 AggregateEnum.Clear。

。小计(AggregateEnum aggType,诠释 groupBy,诠释 totalOn)

小计(AggregateEnum aggType,字符串 groupBy,字符串 totalOn)

这些是最常用的重载。该参数是要插入的聚合类型和对本集团的总列上。被引用的列可以通过索引或名称。后者是一个

我们在上面的例子使用。

。小计(AggregateEnum aggType,诠释 groupBy,诠释 totalOn,字符串标题)

小计(AggregateEnum aggType,字符串 groupBy,字符串 totalOn,串标题)

这些重载标题添加一个额外的参数。标题参数确定被添加到新节点的行被分组确定价值的文本。默认情况下,该值被分 为上显示出来,所以如果你是按国家分组时,节点的行会显示“阿根廷”,“巴西”,等等。如果您设置标题参数为字符串, 如“国家:{}”,则节点的行会显示“国家:阿

根廷”代替。

。小计(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 控件的节点。
05-11 13:06