Page tree
Skip to end of metadata
Go to start of metadata

下面章节的教程中,包含了一些例子用来说明 C1FlexGrid 控件中的一些主要特点。教程通过一步步创建几个简单的项目,详细描述了每个步骤。配套的光盘 CD 中包含了一些可作为参考的更复杂的例子。
这些教程是:


教程

描述

编辑教程

从一个基本的数据输入表格开始, 本教程演示如何实现数据格式化、复选框、下拉列表、输入掩码、数据验证、剪贴板支持。

大纲教程

演示如何使用 C1FlexGrid 的大纲功能来展示结构性(或分层)数据。

数据分析教程

从一个包含不同产品的、各地区的、销售人员的销售数据表格,来展示如何实现动态布局
(列顺序)、自动排序、合并单元格、自动分类汇总和大纲视图。




 编辑教程


本教程由一个基本的数据录入表格开始,然后增加了以下功能:


  1. 格式化
  2. 复选框
  3. 下拉列表
  4. 复杂的数据验证
  5. 剪贴板支持
  6. 自定义编辑器


最终的应用程序将类似于下面:

在 ComponentOne 主页的 Videos 中有一个本教程的视频。


步骤 1/6: 为这个编辑教程创建一个 C1FlexGrid 控件


启动一个新项目并点击工具箱中的 C1FlexGrid 图标向窗体中添加
C1FlexGrid 控件。
然后在窗体中点击或者拖动控件到一个合适的大小。
如果你没有在工具箱中找到 C1FlexGrid 控件,那么请在工具箱中右键单击然后选择"选择项…"。 然后在.Net 组件列表中查找 C1FlexGrid 控件并确保勾选上。 如果你在控件列表中无法找到控件,你也许需要重新安装控件包。


  1. 在属性窗口中为 C1FlexGrid 控件设置以下属性:

    属性

    设置

    Dock

    Fill

    Cols.Count

    5

    Cols.Fixed

    0

  2. 双击窗体的标题区域来打开代码窗口。在文件的顶端添加如下声明代码:


  • Visual Basic


Imports C1.Win.C1FlexGrid


  • C#


      using C1.Win.C1FlexGrid;

这使得 C1FlexGrid 中定义的对象在整个项目都可见,并节省了很多需要敲的代码。
3. 可以通过列任务菜单、C1FlexGrid 列编辑器或者代码中来设计这些列。
在设计器中:


  • 选中表格中的第一列。这将会打开这一列的列任务菜单。
  • 在列标题和数据字段框中,输入 Product
  • 设置列标题和数据字段,其余列如下:

    Column 1

     

    Column Caption

    Region

    Data Field

    Region

    Column 2

     

    Column Caption

    Salesperson

    Data Field

    Salesperson

    Column 3

     

    Column Caption

    Sales

    Data Field

    Sales

    Column 4

     

    Column Caption

    Bonus

    Data Field

    Bonus

    另外,还可以通过 C1FlexGrid 列编辑器来设置这些列:

  • 通过在 C1FlexGrid 列任务菜单中点击设计器打开 C1FlexGrid 列编辑器。关于如何访问 C1FlexGrid 列编辑器的更多细节请查看访问 C1FlexGrid 列编辑器章节 (第 143 页)。
  • 在右侧的窗格中选中 Column 0 。
  • 在左侧窗格中,设置 Name 和 Caption 属性为 Product。
  • 设置 Name 和 Caption 属性,其余列如下:

    Column 1

     

    Name

    Region

    Caption

    Region

    Column 2

     

    Name

    Salesperson

    Caption

    Salesperson

    Column 3

     

    Name

    Sales

    Caption

    Sales

    Column 4

     

    Name

    Bonus

    Caption

    Bonus

    完成后点击 OK 来关闭编辑器。 在代码中:在 Form_Load 事件中添加如下代码:

  • Visual Basic


' 创建列.
Dim cols As String = "Product|Region|Salesperson|Sales|Bonus"
Dim colNames As String() = cols.Split("|")
Dim i%
For i = 0 To C1FlexGrid1.Cols.Count - 1
C1FlexGrid1(0, i) = colNames(信息)
C1FlexGrid1.Cols(信息).Name = colNames(信息) Next


  • C#


//创建列.

string cols = "Product|Region|Salesperson|Sales|Bonus"; string[] colNames = cols.Split(new char[] { '|' }); for (int i = 0; i <= this.c1FlexGrid1.Cols.Count - 1; i++)


{

c1FlexGrid1[0, i] = colNames[i]; c1FlexGrid1.Cols[i].Name = colNames[i];


}
运行程序并遵守以下规定:
就是这样!按下 F5 运行该项目,这样你就可以开始向控件中输入一些数据。按 F2 或者空格键来编辑现有条目,或者只是在现有的条目上键入新数据。



步骤 2/6: 设置列的类型和格式


当显示数字或者日期值时,您通常会希望采用一致的格式来显示这些值。 C1FlexGrid 控件允许你为每一列定制数据类型和格式。这些属性在设计器或者代码中都可以设置。
在设计器中


  1. 在表格中选中 Sales 列。这将会打开 Sales 列的列任务菜单。
  2. 设置 Data Type (数据类型)为 Decimal。
  3. Format String(格式字符串)框中点击省略号按钮打开对话框。
  4. 格式类型中选择 Currency(货币)。
  5. 点击 OK 关闭格式字符串对话框。
  6. 在表格中选中 Bonus 列。这将会打开 Bonus 列的列任务菜单。
  7. 设置数据类型为 Boolean。


另外,还可以通过 C1FlexGrid 的列编辑器来设置数据类型和格式属性:


  1. 通过 C1FlexGrid 任务菜单选择设计器来打开 C1FlexGrid 列编辑器 。 对于如何访问 C1FlexGrid 列编辑器的更多细节,请查看 访问 C1FlexGrid 列编辑器章节。


  1. 在右边的窗格中选择 Sales 列。
  2. 设置 DataType 属性为 Decimal。
  3. 点击 Format 属性旁边的省略号按钮。这将会打开 Format String (格式化字符串)对话框。
  4. 格式化类型 中选择货币
  5. 点击 OK 来关闭 Format String 对话框。
  6. 在右边的窗格中选择 Bonus 列。
  7. 设置 DataType 属性为 Boolean。
  8. 点击 OK 来关闭编辑器窗口。


代码中
要指定列的数据类型和格式,先添加步骤 1/6:为这个编辑教程创建一个C1FlexGrid 控件的代码后再添加下面的代码:


  • Visual Basic

    '设置列的数据类型和格式。
    Dim c As Column = C1FlexGrid1.Cols("Sales") c.DataType = GetType(Decimal)
    ' 货币类型.
    c.Format = "c2" c = C1FlexGrid1.Cols("Bonus")
    c.DataType = GetType(Boolean)
    c.ImageAlign = ImageAlignEnum.CenterCenter

  • C#

    //设置列的数据类型和格式。

    Column c = c1FlexGrid1.Cols["Sales"]; c.DataType = typeof(Decimal);


    // 货币类型.

    c.Format = "c2"; c = c1FlexGrid1.Cols["Bonus"]; c.DataType = typeof(bool);


    c.ImageAlign = ImageAlignEnum.CenterCenter;


    运行程序,并遵守以下规定:
    Sales 列新的代码格式,用来存储和显示货币值, Bonus 列用来处理布尔值。
    如果你在 Sales 列输入一些数字和非数字值,你会发现表格将无法接受这些输入。
    Bonus 列显示成复选框的样子,可以用鼠标、键盘来切换,这是布尔值列的默认行为。

    注意格式化属性,它不以任何方式影响数据本身的值,只影响如何显示。

     步骤 3/6:纳入下拉列表

    录入数据是一个乏味和容易出错的过程。下拉列表是个伟大的发明,因为它极大的减少了你必须做的输入操作,同时也就减少了出错的机会,这样就提高了数据的一致性。
    让我们假设我们的教程项目只涉及三种产品的销售(Applets、Wahoos、和
    Gadgets)。在四个区域(东、南、西、北), 并且这有三名全职销售人员
    (玛丽、莎拉和宝拉)。
    要在 C1FlexGrid 控件中将这个列表变为下拉列表, 所有你必须做的就是分别建立包含了每个项目的字符串(使用字符分割),并将它们分配到每个列对应的 ComboList 属性中去。
    这个属性可以在代码或者设计器中设置。
    在设计器中:


  1. 选中 Product 列。 这将会打开 Product 列事件菜单对话框。
  2. 在 Combo List 框中点击省略号按钮来打开 Combo List 窗口。
  3. 如下所示,输入 Applets、Wahoos、和 Gadgets。



  1. 点击 OK 来关闭 Combo List 对话框。
  2. 选中 Region 列。
  3. 在 Combo List 框中点击省略号 按钮。
  4. 输入 North、South、East、和 West 如下图所示:



  1. 点击 OK
  2. 选中 Salesperson 列。
  3. Combo List 框中点击省略号 按钮。
  4. 输入 Mary、Paula、和 Sarah 如下图所示:



12.选择 Dropdown Combo(下拉组合框)选项。
13.点击 OK。
另外,ComboList 属性同样可以在 C1FlexGrid 列编辑器中设置:


    1. 通过在 C1FlexGrid 任务菜单中选择设计器打开 C1FlexGrid 列编辑器。想要知道对于如何访问 C1FlexGrid 列编辑器的更多细节,请查看 访问 C1FlexGrid 列编辑器章节。
    2. 在右边的窗格中选择 Product 列 。
    3. 在左边的窗格中,设置 ComboList 属性为 Applets|Wahoos|Gadgets。
    4. 在右边的窗格中选择 Region column。
    5. 在左边的窗格中,设置 ComboList 属性为 North|South|East|West。
    6. 在右边的窗格中选择 Salesperson。
    7. 在左边的窗格中,设置 ComboList 属性为|Mary|Paula|Sarah。
    8. 点击 OK 来关闭编辑器.


在代码中:
要添加下拉列表项目,先添加步骤 2/6:设置列的类型和格式的代码后再添加下面的代码:


      • Visual Basic


'设置下拉列表
C1FlexGrid1.Cols("Product").ComboList = "Applets|Wahoos|Gadgets"
C1FlexGrid1.Cols("Region").ComboList = "North|South|East|West" C1FlexGrid1.Cols("Salesperson").ComboList = "|Mary|Paula|Sarah"


      • C#


'设置下拉列表

c1FlexGrid1.Cols["Product"].ComboList = "Applets|Wahoos|Gadgets"; c1FlexGrid1.Cols["Region"].ComboList = "North|South|East|West"; c1FlexGrid1.Cols["Salesperson"].ComboList = "|Mary|Paula|Sarah";


运行程序,并遵守以下规定:
请注意最后一个下拉列表是一个入力框 (文本入力光标)。这允许用户输入不在列表中的其他名字。换句话说,这些值将在下拉列表中可以编辑,而不是一个简单的下拉列表。
按 F5 再次运行该项目,然后移动光标。当您将光标移动到有下拉列表的列上时,下拉列表的按钮才为可见,你可以点击它来显示列表,或者只需要简单输入某个条目的第一个字母,使这个条目在下拉列表中变为高亮。



步骤 4/6: 添加数据验证


如果你为表格中的列指定了数据类型,表格就会确保只有这个类型的数据能够在这一列保存。这有助于防止错误发生,但是你会经常需要更加严格的验
证,以确保输入的数据是正确的。对于这一点,你应该使用 ValidateEdit 事件。
例如,想象一下,反托拉斯法规组织我们在北方地区销售我们的小程序。为了防止数据输入错误而带来昂贵的诉讼,我们希望防止用户在这个下拉列表中输入这个值。
以下事件用来检查在数据输入后编辑框中的数据是否合法, 添加下面的代码到窗体中:


  • Visual Basic

    Private Sub C1FlexGrid1_ValidateEdit(ByVal sender As Object, ByVal e As
    ValidateEditEventArgs) Handles C1FlexGrid1.ValidateEdit
    Dim rgn As String = String.Empty Dim prd As String = String.Empty
    ' 收集我们需要的数据
    Select Case e.Col prd = C1FlexGrid1.Editor.Text
    rgn = C1FlexGrid1(e.Row, "Region") Case 1
    prd = C1FlexGrid1(e.Row, "Product") rgn = C1FlexGrid1.Editor.Text End Select
    ' 我们可以在北部区域卖小程序
    If prd = "Applets" And rgn = "North" Then
    MsgBox("Warning: Regulation #12333AS/SDA-23 forbids " & _
    "the sale of " & prd & " in region " & rgn & ". " & _ "Please verify input.") e.Cancel = True
    End If
    End Sub

  • C#




private void c1FlexGrid1_ValidateEdit( object sender, ValidateEditEventArgs e)
{
string rgn = string.Empty;
string prd = string.Empty; //收集我们需要的数据.
switch (e.Col)
{
case 0:

prd = c1FlexGrid1.Editor.Text; rgn = (string)c1FlexGrid1[e.Row, "Region"]; break; case 1:

prd = (string)c1FlexGrid1[e.Row, "Product"]; rgn = c1FlexGrid1.Editor.Text; break;


}
//我们可以在北部区域卖小程序
if ( prd == "Applets" && rgn == "North" ) {
MessageBox.Show("Warning: Regulation #12333AS/SDA-23 forbids " +
"the sale of " + prd + " in region " + rgn + ". " + "Please verify input."); e.Cancel = true;
}
}



运行程序,并遵守以下规定:
这个模块开始是收集需要验证的输入。请注意,被检查的值要恢复的话请使用 Editor.Text 属性。 这是必要的,因为这次编辑并没有应用到控件中去。如果检查失败了,这个模块将会显示一个警告然后将 Cancel 参数设置为 True,这样可以取消编辑并将单元格重新置为编辑模式,使用户可以再次尝试。
按 F5 再次运行该项目,然后再尝试输入一些错误的值。你会看到该控件将会拒绝它们。


 步骤 5/6: 添加剪贴板的支持


Windows 剪贴板是一个在应用程序之间传输信息的非常有用的设备。
FlexGrid for WinForms 项目中添加剪贴板支持是相当容易的。只需要在代码或者设计器中简单的设置 AutoClipboard 属性为 True ,然后表格就会自动
的处理所有发送到剪贴板的标准键盘命令:如 CTRL+X 或者 SHIFT+DELETE 剪切,CTRL+C 或者 CTRL+INSERT 拷贝,CTRL+V 或者 SHIFT+INSERT 粘贴。
在设计器中:
在属性窗口中定位到 AutoClipboard 属性并将它设置为 True
在代码中:
在添加完步骤 3/6:纳入下拉列表(第 112 页)之后,添加如下代码:


  • Visual Basic


C1FlexGrid1.AutoClipboard = True


  • C#


c1FlexGrid1.AutoClipboard = true;

另一个伟大的 Windows 功能,并与剪贴板密切相关,这就是 OLE 拖放操
作。C1FlexGrid 有两个属性, DragMode 和 DropMode。 这两个属性实现了这个功能。无论是在代码中还是在设计器中,只需要将这个两个属性设置为自动,你就能够将表格中选中的项目拖出程序并放置到其他应用程序中,如 Microsoft
Excel,或者从 Excel 中选择一个范围拖放到 C1FlexGrid 控件中。
在设计器中: 定位到 DragMode 和 DropMode 属性并将它们都设置为 Automatic。
在代码中:
在设置 AutoClipboard 属性后添加如下代码:


  • Visual Basic


C1FlexGrid1.DragMode = DragModeEnum.Automatic
C1FlexGrid1.DropMode = DropModeEnum.Automatic


  • C#


c1FlexGrid1.DragMode = DragModeEnum.Automatic; c1FlexGrid1.DropMode = DropModeEnum.Automatic;
运行程序,并遵守以下规定:按 F5 再次运行该项目,然后试着拷贝和粘贴一些数据。注意,你可以粘贴
一些非法的数据,因为我们的粘贴操作不触发任何的数据验证事件。 这是留给读者的练习。


 步骤 6/6: 包含一个自定义编辑器


C1FlexGrid 拥有强大的内置输入编辑器:输入文字、文字掩码、列表选择、复选框等等。
但是在某些情况下,你可能想使用一个自定义编辑器来代替,也许是
C1Input 库中带的输入控件或者你自己写的输入控件。从版本 2.5 开始,FlexGrid 允许你轻松加愉快的插入自定义编辑器。要在教程工程的 Sales 列附加一个自定义编辑器,从往窗体上添加一个 NumericUpDown 控件开始。在属性窗口中,为 NumericUpDown 控件设置如下属性:


属性

设置

BorderStyle

None

DecimalPlaces

2

Maximum

5000000

ThousandsSeparator

True

Visible

False



在 C1FlexGrid 任务菜单中选择设计器来打开表格的列编辑器。

选中 Sales 列(或代表 Sales 列的第 3 列),之后设置编辑器属性为
NumericUpDown
运行程序,并遵守以下规定:
现在运行该项目,并尝试在 Sales 列中编辑一些值。请注意,表格现在使用
NumericUpDown 控件,而不是内置的编辑器。
这个控件已经进行了适当的位置调整、初始化和管理。当你将光标的焦点移动到不同的单元格中时,这个值将会保存到表格中。
但是这个自定义编辑器的行为与内置编辑器并不完全一样。例如:


  1. 当你开始编辑并键入一个数字,旧的值不会被清除。
  2. 编辑器的大小是不完全正确的(他看起来有点太小)。
  3. 当你使用回车键完成编辑时会有一声提示音出现。


你可以使用几个方法来克服这些问题。一种方法是使用编辑器的事件,但是这将使其难以在其他项目中重用这个控件。另一个方法是创建一个派生类并实现 IC1EmbeddedEditor 接口的一些方法,类似下面的这些代码:


  • Visual Basic

    Public Class MyUpDown Inherits NumericUpDown
    ' 设置初始值
    Public Sub C1EditorInitialize(ByVal value As Object, ByVal editorAttributes As IDictionary)
    ' 为初始值赋值
    value = Convert.ChangeType(value, GetType(Decimal))
    ' 选择进入点
    MyBase.Select(0, Int32.MaxValue)
    End Sub
    ' 设置字体高度以便控件来控制整体高度
    Public Sub C1EditorUpdateBounds(ByVal rc As Rectangle)
    MyBase.FontHeight = rc.Height
    Bounds = rc
    End Sub
    ' 当用户按下回车键,禁止发出蜂鸣声
    Protected Overrides Function ProcessDialogKey(ByVal keyData As Keys) As Boolean
    If (keyData = Keys.Enter) Then
    Parent.Focus()
    If (Parent.Focused) Then SendKeys.Send("{Down}")
    Return True
    End If
    Return MyBase.ProcessDialogKey(keyData)
    End Function

  • C#

    internal class MyUpDown : NumericUpDown
    {
    //设置初始值
    public void C1EditorInitialize(object value,
    System.Collections.IDictionary editorAttributes)
    {
    //为初始值赋值
    Value = (decimal)Convert.ChangeType(value, typeof(decimal));
    //选择进入点
    Select(0, int.MaxValue);
    }
    //设置字体高度以便控件来控制整体高度
    public void C1EditorUpdateBounds(Rectangle rc)
    {
    base.FontHeight = rc.Height;
    Bounds = rc;
    }
    //当用户按下回车键,禁止发出蜂鸣声
    override protected bool ProcessDialogKey(Keys keyData)
    {
    if (keyData == Keys.Enter)
    {
    Parent.Focus(); if (Parent.Focused) SendKeys.Send("{Down}"); return true;
    }
    return base.ProcessDialogKey(keyData);
    }
    }


    上面的代码实现了三个方法:
    C1EditorInitialize 被调用来初始化编辑器。它设置了初始值然后选中整个条目。
    这个将解决刚才提到的第一个问题。因为整个项目被选中,现在输入一个我们想要的字符将会取代目前的内容。
    C1EditorUpdateBounds 被调用来定位正在编辑的单元格。NumericUpDown 控件的高度被设为以字体大小为基础自动增长(这就是为什么它相对单元格看起来太短)。代码设置了编辑器的 FontHeight 属性,所以它将被固定在单元格中。
    ProcessDialogKey 方法被重写了,用来阻止当用户按下回车键发出的提示音。

    大纲教程

    本教程演示如何使用 C1FlexGrid 作为一个大纲视图来显示结构(或层次)数据。
    当作为一个大纲,C1FlexGrid 控件的行为就像一个树形控件,显示一些可以折叠、展开的节点,以展示包含下级数据的分支。
    本教程可以让你加载一个 XML 文档到表格中,它将显示为一颗树。最终的应用程序看起来的效果如下:

     步骤 1/5: 创建控件

    新建一个项目并添加两个控件:
  • 在窗体的顶部附近添加一个命令按钮。
  • 在按钮下面的区域添加一个 C1FlexGrid 控件。


如果你没有在工具箱中找到 C1FlexGrid 控件,那么请在工具箱中右键单击然后选择"选择项…"。 然后在.Net 组件列表中查找 C1FlexGrid 控件并确保勾选上。 如果你在控件列表中无法找到控件,你也许需要重新安装控件包。


  1. 在属性窗口中设置如下属性: 命令按钮

    属性

    设置

    Dock

    Top

    Text

    "Open XML File…"

    C1FlexGrid

    属性

    设置

    Dock

    Fill

  2. 双击窗体的标题区域来打开代码窗口。在文件的最上方添加如下代码段:


  • Visual Basic


Imports C1.Win.C1FlexGrid


  • C#


   using C1.Win.C1FlexGrid;

这使得 C1FlexGrid 中定义的对象在整个项目都可见,并节省了很多需要敲的代码。
3. 可以在设计器中使用属性窗口和编辑器来设置表格,或者在代码中输入
(或复制)以下代码: 在设计器中:
在属性窗口中为 C1FlexGrid 控件设置以下属性:


属性

设置

Cols.Count

2

Cols.Fixed

0

ExtendLastCol

True

Rows.Count

1

Tree.Column

0

Tree.Style

SimpleLeaf


为表格设置样式:


    • 在 C1FlexGrid 任务菜单中选择样式打开 C1FlexGrid 样式编辑器。想要知道对于如何访问 C1FlexGrid 样式编辑器的更多细节,请查看 访问 C1FlexGrid 样式编辑器章节。
    • 在内置样式中选择 Normal 。
    • 设置 Border.Style 为 None,设置 TextAlign 属性为 LeftCenter,设置 WordWrap 属性为 False。
    • 点击添加按钮。
    • 将 CustomStyle1 重命名为 Data。
    • 设置 BackColor 属性为 Control。
    • 点击 OK 来关闭编辑器。


设置表格中的列:


    • 在表格中选中 Column 0。这将打开第 0 列的列任务菜单。
    • 将 Column Caption 设置为 Element。
    • 取消勾选 Allow Editing 复选框。
    • 选择 Column 1.
    • 将 Column Caption 设置为 Text。


另外, 这些列也可以通过 C1FlexGrid 列编辑器来设置:


    • 通过在 C1FlexGrid 任务菜单中选择设计器来打开 C1FlexGrid 列编辑器。想要知道对于如何访问C1FlexGrid列编辑器的细节,请查看访问C1FlexGrid 列编辑器章节
    • 在右侧窗格中选择 Column 0。
    • 在左侧窗格中,将 AllowEditing 属性设置为 False ,设置 Caption 属性为Element。


    • 在右侧窗格中选择 Column 1。
    • 在左侧窗格中,将 Caption 属性设置为 Text
    • 点击 OK 来关闭编辑器。


在代码中:


    • Visual Basic




Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
' 初始化表格
C1FlexGrid1.Rows.Count = 1
C1FlexGrid1.Cols.Count = 2
C1FlexGrid1.Cols.Fixed = 0
C1FlexGrid1.ExtendLastCol = True
C1FlexGrid1(0, 0) = "Element"
C1FlexGrid1(0, 1) = "Text"
' 初始化大纲的树结构
C1FlexGrid1.Tree.Column = 0
C1FlexGrid1.Tree.Style = TreeStyleFlags.SimpleLeaf
C1FlexGrid1.Cols(0).AllowEditing = False
' 初始化样式
C1FlexGrid1.Styles.Normal.Border.Style = BorderStyleEnum.None
C1FlexGrid1.Styles.Normal.TextAlign = TextAlignEnum.LeftCenter
C1FlexGrid1.Styles.Normal.WordWrap = False Dim cs As CellStyle = C1FlexGrid1.Styles.Add("Data") cs.BackColor = SystemColors.Control
End Sub




    • C#

      private void Form1_Load( System.object sender, System.EventArgs e)
      {
      //初始化表格

      c1FlexGrid1.Rows.Count = 1; c1FlexGrid1.Cols.Count = 2; c1FlexGrid1.Cols.Fixed = 0; c1FlexGrid1.ExtendLastCol = true; c1FlexGrid1[0, 0] = "Element";

      c1FlexGrid1[0, 1] = "Text";


      // 初始化大纲的树结构

      c1FlexGrid1.Tree.Column = 0; c1FlexGrid1.Tree.Style = TreeStyleFlags.SimpleLeaf; c1FlexGrid1.Cols[0].AllowEditing = false;


      //初始化样式
      c1FlexGrid1.Styles.Normal.Border.Style = BorderStyleEnum.None; c1FlexGrid1.Styles.Normal.TextAlign = TextAlignEnum.LeftCenter; c1FlexGrid1.Styles.Normal.WordWrap = false; CellStyle cs = c1FlexGrid1.Styles.Add("Data"); cs.BackColor = SystemColors.Control;
      }



      运行程序,并遵守以下规定:
      代码从一开始就设置表格的布局和标题的文本内容。

      接下来,初始化大纲树属性并将第一列的 AllowEditing 属性设为 False 以防止 XML 节点能够被编辑。请注意,用户仍可以在包含每个 XML 节点数据的下一列进行数据的编辑。
      现在空间已经设置好了。我们可以开始添加一些代码。

      步骤 2/5:读取数据并创建大纲

      要读取数据,并建立大纲,向 Button1_Click 事件中添加一些代码和
      GetXMLData 事物。
      1. 双击命令按钮,将下面的代码添加到 Button1_Click 事件中去:
    • Visual Basic

      Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
      System.EventArgs) Handles Button1.Click
      ' 取得文件名称
      Dim fo As OpenFileDialog = New OpenFileDialog() fo.DefaultExt = "xml"
      fo.Filter = "XML Files (.xml)|.xml"
      If fo.ShowDialog() <> Windows.Forms.DialogResult.OK Then Exit Sub
      ' 读取 XML 文件
      Dim xdoc As System.Xml.XmlDocument = New System.Xml.XmlDocument() xdoc.Load(fo.FileName)
      ' 停止重绘,以提高速度。
      C1FlexGrid1.Redraw = False
      ' 填充表格
      C1FlexGrid1.Rows.Count = 1
      GetXMLData(xdoc.ChildNodes(1), 0)
      ' 自动调整树的大小。
      C1FlexGrid1.AutoSizeCol(0)
      ' 显示 0、1、2 层
      C1FlexGrid1.Tree.Show(2)
      ' 开始重绘
      C1FlexGrid1.Redraw = True
      End Sub

    • C#

      private void button1_Click(System.object sender, System.EventArgs e)
      {
      //取得文件名称
      OpenFileDialog fo = new OpenFileDialog(); fo.DefaultExt = "xml"; fo.Filter = "XML Files (.xml)|.xml"; if ( fo.ShowDialog() != DialogResult.OK ) return;
      //读取 XML 文件
      System.Xml.XmlDocument xdoc = new System.Xml.XmlDocument(); xdoc.Load(fo.FileName);
      //停止重绘,以提高速度。
      c1FlexGrid1.Redraw = false;
      //填充表格
      c1FlexGrid1.Rows.Count = 1;

      GetXMLData(xdoc.ChildNodes[1], 0);


      //自动调整树的大小。
      c1FlexGrid1.AutoSizeCol(0);
      //显示 0、1、2 层
      c1FlexGrid1.Tree.Show(2);
      //开始重绘
      c1FlexGrid1.Redraw = true;
      }



      请遵守以下规定:
      这个流程一开始是显示一个 OpenFileDialog 用来让用户选择一个 XML 文件加载到表格中。
      当文件被选中,程序就开始加载文件到 XmlDocument 对象,并将文件中的内容解析到内存中去。
      这个流程之后开始设置表格的重绘属性为 False 来控制表格暂停重绘。这种技显著的提高了程序的性能,你可以在向 C1FlexGrid 表格中添加大量数据的时候使用这个方法。
      接下来,这个流程清除了为 1 的任何数据,并调用 GetXMLData 方法来填充数据到 XmlDocument。这个 GetXMLData 方法是这个指南中列出的条目中,最重要的一环。
      在表格已被填充后,例程使用 AutoSizeCol 方法来根据第一列的内容来调整列的宽度,之后 Show 方法用来将需要显示的层级扩展到 0、 1、 和 2。 之后例程将 Redraw 属性设置回 True 以便 grid 开始重绘。
      2. 这个 GetXMLData 例程是本教程中最有趣的一个。它贯穿整个
      XMLDocument 对象,并建立大纲的树形结构。将下面的代码添加到窗体中去:

    • Visual Basic

      Private Sub GetXMLData(ByVal node As System.Xml.XmlNode, ByVal level As Integer)
      ' 跳过注释节点
      If node.NodeType = System.Xml.XmlNodeType.Comment Then
      Exit Sub
      End If
      ' 为这一个节点添加一个新行
      Dim row As Integer = C1FlexGrid1.Rows.Count
      C1FlexGrid1.Rows.Add()
      ' 为这个新行添加数据
      C1FlexGrid1(row, 0) = node.Name
      If node.ChildNodes.Count = 1 Then
      C1FlexGrid1(row, 1) = node.InnerText
      C1FlexGrid1.SetCellStyle(row, 1, C1FlexGrid1.Styles("Data")) End If
      ' 如果这个节点有"Name" 子节点的话,将它保存起来作为一个 ToolTip 提示使用。
      If node.ChildNodes.Count > 0 Then
      Dim ndName As System.Xml.XmlNode = node.SelectSingleNode("Name")
      If Not (ndName Is Nothing) Then
      C1FlexGrid1.Rows(row).UserData = ndName.InnerText
      End If
      End If
      ' 如果此节点有子节点,将它们都取出来
      If node.ChildNodes.Count > 1 Then
      ' 将当前行作为节点
      C1FlexGrid1.Rows(row).IsNode = True C1FlexGrid1.Rows(row).Node.Level = level
      ' 使用递归来取得子节点
      Dim child As System.Xml.XmlNode
      For Each child In node.ChildNodes
      GetXMLData(child, level + 1)
      Next
      End If
      End Sub

    • C#

      private void GetXMLData(System.Xml.XmlNode node, int level)
      {
      //跳过注释节点
      if ( node.NodeType == System.Xml.XmlNodeType.Comment )
      {
      return;
      }
      //为这一个节点添加一个新行
      int row = c1FlexGrid1.Rows.Count; c1FlexGrid1.Rows.Add();
      //为这个新行添加数据

      c1FlexGrid1[row, 0] = node.Name; if ( node.ChildNodes.Count == 1 )


      {

      c1FlexGrid1[row, 1] = node.InnerText; c1FlexGrid1.SetCellStyle(row, 1, c1FlexGrid1.Styles["Data"]);


      }
      //如果这个节点有"Name" 子节点的话,将它保存起来作为一个 ToolTip 提示使用。
      if (node.ChildNodes.Count > 0)
      {
      System.Xml.XmlNode ndName = node.SelectSingleNode("Name"); if (ndName != null)
      {

      c1FlexGrid1.Rows[row].UserData = ndName.InnerText;


      }
      }
      //如果此节点有子节点,将它们都取出来
      if ( node.ChildNodes.Count > 1 )
      {
      //将当前行作为节点

      c1FlexGrid1.Rows[row].IsNode = true;

      c1FlexGrid1.Rows[row].Node.Level = level;


      //使用递归来取得子节点
      foreach (System.Xml.XmlNode child in node.ChildNodes) GetXMLData(child, level + 1);
      }
      }


      请遵守以下规定:
      程序一开始跳过了 XML 注释节点,然后使用 Rows.Add 来向表格中添加一个新行。
      接下来,程序开始设置节点的名称并检查该节点是否拥有孩子节点。在这种情况下,该节点被解释为一个数据节点,之后将该节点的 InnerText 属性复制到新行的第二列。代码还设置了当窗体被创建时,包含数据的单元格的样式为自定义的"Data"样式 。接下来的代码块检查看看是否这个节点包含一个名为
      "name"的子节点。如果有,那么"name"节点的内容会被分配到新行的
      UserData 属性中去。这个值将会被用于实施工具提示,这样即使节点名称被折叠起来了,用户也能够看到。
      最后,如果该节点有孩子节点, GetXMLData 程序会调用自身来递归添加他们到表格中。
      运行程序,并遵守以下规定: 该项目可以加载 XML 并显示它们,用户可以点击折叠或者展开节点。
      接下来的步骤中会添加一些改进,使得应用程序更加容易使用。

       步骤 3/5:添加自定义的鼠标和键盘处理

      C1FlexGrid 为你提供了展开和折叠的操作,但是你可以扩展并自己定制这些行为。每当一个分支被展开或折叠起来,控件会触发 BeforeCollapse 和 AfterCollapse 事件,所以你可以在这些事件中做一些回应。此外,您可以在代码中使用 Collapsed 属性来获取和设置每个分支的折叠状态。
      在本教程中,我们将捕获当用户鼠标双击或按下回车键来展开或者折叠节点时的 DoubleClickKeyPress 事件。添加下面的 DoubleClickKeyPress 事件代码到窗体上:
       Visual Basic
      Private Sub C1FlexGrid1_DoubleClick(ByVal sender As Object, ByVal e As
      EventArgs) Handles C1FlexGrid1.DoubleClick
      If C1FlexGrid1.MouseCol = 0 Then
      ToggleNodeState()
      End If
      End Sub
      Private Sub C1FlexGrid1_KeyPress(ByVal sender As Object, ByVal e As
      KeyPressEventArgs) Handles C1FlexGrid1.KeyPress
      If e.KeyChar = vbCr Then
      ToggleNodeState()
      End If
      End Sub
      Private Sub ToggleNodeState()
      ' 如果当前行不是节点,则什么也不做
      Dim r As Row = C1FlexGrid1.Rows(C1FlexGrid1.Row)
      If Not r.IsNode Then Exit Sub
      '切换折叠状态
      r.Node.Collapsed = Not r.Node.Collapsed End Sub
       C#

      private void c1FlexGrid1_DoubleClick( object sender, EventArgs e)
      {
      if ( c1FlexGrid1.MouseCol == 0 )
      {
      ToggleNodeState();
      }
      }
      private void c1FlexGrid1_KeyPress( object sender, KeyPressEventArgs e)
      {
      if ( e.KeyChar == 13 )
      {
      ToggleNodeState();
      }
      }
      private void ToggleNodeState()
      {
      //如果当前行不是节点,则什么也不做

      Row r = c1FlexGrid1.Rows[c1FlexGrid1.Row]; if (! r.IsNode ) return;


      //切换折叠状态
      r.Node.Collapsed = !r.Node.Collapsed;
      }


      运行程序,并遵守以下规定:
      事件处理程序检查用户是否双击第一列或按下回车键,然后调用
      ToggleNodeState 程序。ToggleNodeState 检查当前行是否是一个节点行,如果是,则切换 Collapsed 属性值。

       步骤 4/5:允许/阻止编辑

      回想一下,我们设置第一列的 AllowEditing 属性为 False。这可以防止用户编辑第一列中的任何单元格。我们也想防止用户在节点行的第二列输入任何数
      据。要做到这一点,添加下面的代码来处理 BeforeEdit 事件:
    • Visual Basic


Private Sub C1FlexGrid1_BeforeEdit(ByVal sender As Object, ByVal e As
RowColEventArgs) Handles C1FlexGrid1.BeforeEdit
' 如果当前行是一个节点,则不允许编辑
Dim r As Row = C1FlexGrid1.Rows(C1FlexGrid1.Row)
If r.IsNode Then e.Cancel = True End Sub


    • C#

      private void c1FlexGrid1_BeforeEdit( object sender, RowColEventArgs e)
      {
      //如果当前行是一个节点,则不允许编辑

      Row r = c1FlexGrid1.Rows[c1FlexGrid1.Row]; if (r.IsNode ) e.Cancel = true;


      }


       步骤 5/5: 实现工具提示

      在结束本教程前,我们将向大纲中添加工具提示。这个工具提示将把每一行中 UserData 属性中保存的上述 GetXMLData 的文本显示出来。 当用户将鼠标移到它的父节点时,工具提示将显示"Name" 节点的内容。这是非常有用的,因为当父节点折叠起来时,"Name"节点是不可见的。


    1. 添加一个 ToolTip 控件到窗体上。
    2. 添加下面的代码来处理表格上的 MouseMove 事件:


 Visual Basic
Private Sub C1FlexGrid1_MouseMove(ByVal sender As Object, ByVal e As
MouseEventArgs) Handles C1FlexGrid1.MouseMove
' 为当前单元格检查 ToolTip
Dim tip As String
If C1FlexGrid1.MouseCol = 0 And C1FlexGrid1.MouseRow > 0 Then
tip = C1FlexGrid1.Rows(C1FlexGrid1.MouseRow).UserData
' 如果与当前提示不同,则设置 ToolTip。
If tip <> ToolTip1.GetToolTip(C1FlexGrid1) Then
ToolTip1.SetToolTip(C1FlexGrid1, tip)
End If
End If
End Sub
 C#


private void c1FlexGrid1_MouseMove( object sender, MouseEventArgs e)
{
//为当前单元格检查 ToolTip
string tip; if ( c1FlexGrid1.MouseCol == 0 && c1FlexGrid1.MouseRow > 0 )
{

tip = (string)c1FlexGrid1.Rows[c1FlexGrid1.MouseRow].UserData;


//如果与当前提示不同,则设置 ToolTip。
if ( tip != toolTip1.GetToolTip(c1FlexGrid1) )
{
toolTip1.SetToolTip(c1FlexGrid1, tip);
}
}
}




运行程序,并遵守以下规定:
代码首先使用 MouseRow 属性和 MouseCol 属性来检查当前鼠标下的单元格。如果鼠标是在包含 ToolTip 文本行的第一列,则检索该行文本。否则,
ToolTip 文本设置为 Nothing。
然后程序会比较当前和新的 ToolTip 文本,如有必要的话则通过调用
ToolTip 控件的 SetToolTip 方法来更新文本。
这样就结束了本教程。你可以在很多方面来扩展这个项目,包括将改动保存到 XML 文档中,添加、删除和移动节点,为不同类型的数据使用不同的样式等等。


 数据分析教程


本教程结合了一些 C1FlexGrid 控件非常有用的功能来实现数据表的动态视图。这个应用程序是从一个简单的数据绑定表格开始,表格中包含了销售数据
(来自 NorthWind 数据库),之后添加了一下功能:


    • 动态布局(列顺序)
    • 自动排序
    • 合并单元格
    • 自动合计
    • 大纲视图


最终的程序看起来如下图所示。用户可以拖动前三列来分组数据,包括


salesperson、 country、 和 product name。当一列被拖动,最终合计会自动的重新计算并重建大纲树。


 步骤 1/4: 为数据分析教程创建 C1FlexGrid 控件


创建一个新的项目,并在工具箱中点击 C1FlexGrid 图标来在窗体中添加一
个 C1FlexGrid 控件,然后点击窗体并拖动控件直到控件有一个合适大小。
如果你没有在工具箱中找到 C1FlexGrid 控件,那么请在工具箱中右键单击然后选择"选择项…"。 然后在.Net 组件列表中查找 C1FlexGrid 控件并确保勾选上。 如果你在控件列表中无法找到控件,你也许需要重新安装控件包。


    1. C1FlexGrid 事件菜单中,点击 Dock 来将控件适用到父容器中。将表格的 Dock 属性设置为 Fill 以便表格填充整个窗体。
    2. 双击窗体标题栏区域来打开代码窗口。在文件的最上端,添加下面的代码段:


    • Visual Basic


Imports System.Data.OleDb
Imports System.ComponentModel Imports C1.Win.C1FlexGrid


    • C#


Using System.Data.OleDb;
Using System.ComponentModel;
Using C1.Win.C1FlexGrid;
这使得 C1FlexGrid 中定义的对象和 OleDb 程序集在整个项目都可见,并节省了很多需要敲的代码。


 步骤 2/4: 初始化和填充表格


要设置表格并用我们想要分析的销售数据来填充表格,可以在设计器中或在代码中设置布局属性和样式属性,并使用 GetDataSource 方法来填充表格。


    1. 在设计器中或在代码中设置布局属性和样式属性。


在设计器中: 在属性窗口中,设置如下属性:


属性

设置

AllowEditing

False

AllowSorting

None

AllowMerging

Nodes

ExtendLastCol

True

SelectionMode

Cell

Tree.Style

Simple

Tree.Column

1


      • 通过在 C1FlexGrid 任务菜单选择样式打开 C1FlexGrid 样式编辑器。想要知道对于如何访问 C1FlexGrid 样式编辑器的更多细节,请查看访问 C1FlexGrid 样式编辑器章节
      • 从内置样式列表中选择 Normal
      • 设置 Border.Style 属性为 None,设置 Trimming 属性为 EllipsisCharacter。
      • 从内置样式列表中选择 Subtotal0
      • 设置 BackColor 属性为 Gold,设置 ForeColor 属性为 Black。
      • 为 Subtotal1 和 Subtotal2 设置如下属性:

        Subtotal1

         

        BackColor

        Khaki

        ForeColor

        Black

        Subtotal2

         

        BackColor

        LightGoldenrodYellow

        ForeColor

        Black

      • 点击 OK 来关闭编辑器。


在代码中:
添加下面的代码到 Form_Load 事件中来设置表格的布局和样式:


      • Visual Basic




Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As EventArgs) Handles MyBase.Load
' 初始化表格的布局/行为。
C1FlexGrid1.AllowEditing = False
C1FlexGrid1.AllowSorting = AllowSortingEnum.None
C1FlexGrid1.AllowMerging = AllowMergingEnum.Nodes
C1FlexGrid1.SelectionMode = SelectionModeEnum.Cell
C1FlexGrid1.ExtendLastCol = True
C1FlexGrid1.Cols(0).Width = C1FlexGrid1.Cols.DefaultSize / 4
C1FlexGrid1.Tree.Style = TreeStyleFlags.Simple C1FlexGrid1.Tree.Column = 1
' 初始化表格样式。
C1FlexGrid1.Styles.Normal.Border.Style = BorderStyleEnum.None
C1FlexGrid1.Styles.Normal.Trimming = StringTrimming.EllipsisCharacter Dim s As CellStyle = C1FlexGrid1.Styles(CellStyleEnum.GrandTotal) s.BackColor = Color.Black
s.ForeColor = Color.White s = C1FlexGrid1.Styles(CellStyleEnum.Subtotal0) s.BackColor = Color.Gold
s.ForeColor = Color.Black s = C1FlexGrid1.Styles(CellStyleEnum.Subtotal1) s.BackColor = Color.Khaki
s.ForeColor = Color.Black s = C1FlexGrid1.Styles(CellStyleEnum.Subtotal2) s.BackColor = Color.LightGoldenrodYellow
s.ForeColor = Color.Black
End Sub


C#


private void Form1_Load( System.object sender, EventArgs e)
{
//初始化表格的布局/行为。

c1FlexGrid1.AllowEditing = false; c1FlexGrid1.AllowSorting = AllowSortingEnum.None; c1FlexGrid1.AllowMerging = AllowMergingEnum.Nodes; c1FlexGrid1.SelectionMode = SelectionModeEnum.Cell; c1FlexGrid1.ExtendLastCol = true; c1FlexGrid1.Cols[0].Width = c1FlexGrid1.Cols.DefaultSize / 4; c1FlexGrid1.Tree.Style = TreeStyleFlags.Simple; c1FlexGrid1.Tree.Column = 1;


//初始化表格样式。

c1FlexGrid1.Styles.Normal.Border.Style = BorderStyleEnum.None; c1FlexGrid1.Styles.Normal.Trimming = StringTrimming.EllipsisCharacter; CellStyle s = c1FlexGrid1.Styles[CellStyleEnum.GrandTotal]; s.BackColor = Color.Black;

s.ForeColor = Color.White; s = c1FlexGrid1.Styles[CellStyleEnum.Subtotal0]; s.BackColor = Color.Gold;

s.ForeColor = Color.Black; s = c1FlexGrid1.Styles[CellStyleEnum.Subtotal1]; s.BackColor = Color.Khaki;

s.ForeColor = Color.Black; s = c1FlexGrid1.Styles[CellStyleEnum.Subtotal2]; s.BackColor = Color.LightGoldenrodYellow;


s.ForeColor = Color.Black;
}



常规的一开始设置表格的布局和一些样式。


    1. 通过添加下面的代码到 Form_Load 事件中来将 C1FlexGrid 绑定到数据源。


    • Visual Basic


' 将 C1FlexGrid 绑定到数据源。
C1FlexGrid1.DataSource = GetDataSource()


    • C#


//将 C1FlexGrid 绑定到数据源。
c1FlexGrid1.DataSource = GetDataSource();
下面例行列出通过结合 GetDataSource 方法来创建一个数据源。


    1. 将最后三列的 AllowDragging 属性设置为 False,用来锁定最后三列位


置。这么做的目的是为了防止用户在这些列中做数据分组(这些列中的值是由每一行的不同得来的)。这个属性可以在在设计器中或者在代码中设置:在设计器中:


      • 在表格中选择 Column 4。这将会打开 Column 4 的列任务菜单。
      • 取消勾选 Allow Dragging 复选框。
      • 为 Column 5 和 Column 6 重复做上面两步。


另外, 这个 AllowDragging 属性同样可以在 C1FlexGrid 列编辑器中设置:


      • C1FlexGrid 任务菜单中选择设计器来打开 C1FlexGrid 列编辑器。想要知道对于如何访问 C1FlexGrid 列编辑器的更多细节,请查看访问 C1FlexGrid 列编辑器章节(第 143 页)。
      • 在右侧窗格中选择 Column 4。
      • 在左侧窗格中,设置 AllowDragging 属性为 False。
      • 将 Column 5 和 Column 6 的 AllowDragging 属性设置为 False。
      • 不要关闭编辑器。


在代码中:
将下面的代码添加到 Form_Load 事件中:
Visual Basic
' 防止用户拖动最后三列。
C1FlexGrid1.Cols(4).AllowDragging = False
C1FlexGrid1.Cols(5).AllowDragging = False
C1FlexGrid1.Cols(6).AllowDragging = False


      • C#


//防止用户拖动最后三列。

c1FlexGrid1.Cols[4].AllowDragging = false; c1FlexGrid1.Cols[5].AllowDragging = false; c1FlexGrid1.Cols[6].AllowDragging = false;




    1. 将 Sales Amount 列的 Format 属性设置一下,以便总和可以显示为货币样式。


这个操作可以在设计器中或者在代码中做到:在设计器中:


      • 在表格中选择 Column 6。
      • 在 Format String 框中点击省略号按钮来打开 Format String 窗口。
      • 在 Format type 中选择 Currency(货币)。
      • 点击 OK 来关闭 Format String 窗口。


另外, Format 属性也可以通过使用 C1FlexGrid 列编辑器来设置:


      • C1FlexGrid 列编辑器中,在右侧窗格中选择 Column 6。
      • 在左侧窗格中,点击 Format 属性旁边的省略号按钮来打开Format String 对话框。
      • 在 Format type 中选择 Currency(货币)。
      • 点击 OK 来关闭 Format String 窗口。
      • 点击 OK 来关闭编辑器。


在代码中:


      • Visual Basic


' 在 Sales Amount 列显示货币值。
C1FlexGrid1.Cols(6).Format = "c"


      • C#


//在 Sales Amount 列显示货币值。

c1FlexGrid1.Cols[6].Format = "c";




    1. GetDataSource 方法创建表格中显示的数据表。该例程是非常基本的,除了检索数据的 SQL 语句。大多数人不手动编写 SQL 语句,一般使用虚拟设计器如 Visual Studio 或者 Microsoft Access 来做。


将下面的代码添加到窗体中。请注意,您可能必须稍微更改一下连接字符串,因为它引用了 NorthWind 数据库,该数据库文件可能是在您系统中不同的文件夹中:
 Visual Basic


Private Function GetDataSource() As DataTable
' 创建连接字符串。
Dim conn As String = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\Program Files\ComponentOne Studio.NET
2.0\Common\Nwind.mdb"
' 创建 SQL 语句。
Dim rs As String = _
"SELECT Employees.LastName,Orders.ShipCountry," & _
"Categories.CategoryName,Products.ProductName,Orders.OrderDate," & _

"[Quantity]*[Products].[UnitPrice] AS [Sale Amount] " & _


"FROM (Categories INNER JOIN Products " & _
"ON Categories.CategoryID = Products.CategoryID) " & _
"INNER JOIN ((Employees INNER JOIN Orders " & _
"ON Employees.EmployeeID = Orders.EmployeeID) " &
_

"INNER JOIN [Order Details] " & _

"ON Orders.OrderID = [Order

Details].OrderID) " &
_

"ON Products.ProductID = [Order Details].ProductID " & _


"ORDER BY Employees.LastName,Orders.ShipCountry," & _ "Categories.CategoryName;"
' 检索数据并放到 Dataset 中。
Dim da As OleDbDataAdapter = New OleDbDataAdapter(rs, conn) Dim ds As DataSet = New DataSet() da.Fill(ds)
' 返回数据表
GetDataSource = ds.Tables(0)
End Function




C#


private DataTable GetDataSource()
{
//创建连接字符串。
string conn = "Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data Source=C:
Program Files
ComponentOne Studio.NET

2.0\\Common
Nwind.mdb";

//创建 SQL 语句。
string rs =
"SELECT Employees.LastName,Orders.ShipCountry," +
"Categories.CategoryName,Products.ProductName,Orders.OrderDate," +

"[Quantity]*[Products].[UnitPrice] AS [Sale Amount] " +


"FROM (Categories INNER JOIN Products " +
"ON Categories.CategoryID = Products.CategoryID) " +
"INNER JOIN ((Employees INNER JOIN Orders " +

"ON Employees.EmployeeID = Orders.EmployeeID) " + "INNER JOIN [Order Details] " +


"ON

Orders.OrderID = [Order Details].OrderID) " +

"ON Products.ProductID = [Order Details].ProductID " +


"ORDER BY Employees.LastName,Orders.ShipCountry," + "Categories.CategoryName;";
//检索数据并放到 Dataset 中。
OleDbDataAdapter da = new OleDbDataAdapter(rs, conn); DataSet ds = new DataSet(); da.Fill(ds);
//返回数据表

return ds.Tables[0];


}



你会看到一个普通的有前瞻性的表格,它可以让你移动列,并浏览数据。但是,这些数据没有一个明确的结构,这个表包含了几千条记录,所以想要知道得到的数据意味着什么是相当困难的。


 步骤 3/4: 允许自动排序


在整理数据的第一步是排序。此外,我们想,当用户重新安排这些列时,让这些数据能够自动排序。
在用户重新安排这些列之后,C1FlexGrid 控件触发 AfterDragColumn 事件。我们将添加一个事件处理程序,以基础数据表中的数据进行排序。(如果表格处在非绑定模式,我们可以使用 Sort 方法来做到这一点。)
向窗体中添加下面的代码,用来在用户拖动列的时候排序数据记录和重建合计:


    • Visual Basic

      Private Sub C1FlexGrid1_AfterDragColumn(ByVal sender As Object, ByVal e
      As
      DragRowColEventArgs) Handles C1FlexGrid1.AfterDragColumn
      ' 当用户拖动列的时候排序数据。
      ' 这将导致数据刷新,移除所有合计和触发 AfterDataRefresh 事件,并重建合计。
      Dim sort As String = C1FlexGrid1.Cols(1).Name & ", " & _
      C1FlexGrid1.Cols(2).Name & ", " & _
      C1FlexGrid1.Cols(3).Name
      Dim dt As DataTable = C1FlexGrid1.DataSource dt.DefaultView.Sort = sort
      End Sub

    • C#

      private void c1FlexGrid1_AfterDragColumn( object sender, DragRowColEventArgs e)
      {
      //当用户拖动列的时候排序数据。
      //这将导致数据刷新,移除所有合计和触发 AfterDataRefresh 事件,并重建合计。

      string sort = c1FlexGrid1.Cols[1].Name + ", " + c1FlexGrid1.Cols[2].Name + ", " + c1FlexGrid1.Cols[3].Name;


      DataTable dt = (DataTable)c1FlexGrid1.DataSource; dt.DefaultView.Sort = sort;
      }



      运行该项目,并尝试通过拖动前三列的标题来重新对它们排序。每当你移动一列,数据将自动进行排序,这将使得它更加容易理解。


      在下一个步骤中,我们将添加合计和一个大纲树。 

       步骤 4/4: 添加合计和大纲树

      当表格在绑定模式下使用时,任何数据源的变化都会导致表格触发
      AfterDataRefresh 事件。这个事件是向表格中插入分类汇总和创建大纲树的理想代码场所。添加下面的 AfterDataRefresh 事件代码处理到窗体中:
    • Visual Basic

      Private Sub C1FlexGrid1_AfterDataRefresh(ByVal sender As Object, ByVal e
      As ListChangedEventArgs) Handles C1FlexGrid1.AfterDataRefresh ' Sale Amount 的总和。
      Dim totalOn As Integer = C1FlexGrid1.Cols("Sale Amount").SafeIndex Dim caption As String = "Total for {0}"
      ' 计算三层的总和。
      C1FlexGrid1.Subtotal(AggregateEnum.Sum, 0, 1, totalOn, caption)
      C1FlexGrid1.Subtotal(AggregateEnum.Sum, 1, 2, totalOn, caption) C1FlexGrid1.Subtotal(AggregateEnum.Sum, 2, 3, totalOn, caption)
      ' 将大纲树第二级折叠起来。
      C1FlexGrid1.Tree.Show(2)
      ' 表格自动调整大侠以适应大纲树。
      C1FlexGrid1.AutoSizeCols(1, 1, 1000, 3, 30, AutoSizeFlags.IgnoreHidden)
      End Sub

    • C#

      private void c1FlexGrid1_AfterDataRefresh( object sender, ListChangedEventArgs e)
      {
      // Sale Amount 的总和。

      int totalOn = c1FlexGrid1.Cols["Sale Amount"].SafeIndex; string caption = "Total for {0}";


      // 计算三层的总和。
      c1FlexGrid1.Subtotal(AggregateEnum.Sum, 0, 1, totalOn, caption); c1FlexGrid1.Subtotal(AggregateEnum.Sum, 1, 2, totalOn, caption); c1FlexGrid1.Subtotal(AggregateEnum.Sum, 2, 3, totalOn, caption);
      //将大纲树第二级折叠起来。
      c1FlexGrid1.Tree.Show(2);
      //表格自动调整大侠以适应大纲树。
      c1FlexGrid1.AutoSizeCols(1, 1, 1000, 3, 30, AutoSizeFlags.IgnoreHidden);
      }


      代码首先获得 Sale Amount 列的索引,本教程中,这个索引始终是相同的(Column 6)。按照索引通常比硬编码要好,但是,因为如果有人在 SQL 语句中添加了多个字段,该索引将会发生改变。
      代码调用了 C1FlexGrid.的 Subtotal 方法来对数据进行分组并为合计添加新行。这个新行将会自动配置成大纲树的节点(它们的 IsNode 被设置为 True),以便合计和折叠起来。
      试着拖动一些列,你可以清楚的看到 country、product category 或者
      salesperson 的合计。当然你如果想看到更多细节的话,也可以展开树的节点。
      注意,表格是可以编辑的,改变 Sale Amount 列的值将会再次触发
      AfterDataRefresh 事件,并且合计也会自动的更新。
      这样就结束了本教程。

  • No labels