65.9K
CodeProject 正在变化。 阅读更多。
Home

.NET CF 自定义 DataGrid 格式化

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (16投票s)

2007年8月29日

CPOL

4分钟阅读

viewsIcon

95066

downloadIcon

3406

本文将介绍如何在 DataGrid 中自定义单个单元格的格式,并且该方法适用于 Compact Framework。

Screenshot - GridSample.png

引言

DataGrid 是 Compact Framework 中一个强大的控件,但要实现对单个单元格的自定义格式化,并控制其“自定义”的原因和方式,并非易事。

本文在 Mazdak 撰写的 这篇文章的基础上进行了扩展,这篇文章几乎实现了我需要的所有功能,但自定义“逻辑”的灵活性还不够。

重要提示

在使用此代码之前,有一些重要的注意事项,其中最重要的是确保安装了正确版本的 .NET Compact Framework。我将非常仔细地说明这一点 - 您需要 .NET CF 版本 2 Service Pack 2。

SP2 部分是关键,因为此版本将 DataGridTextBoxColumn 类的 Paint 事件设置为 virtual,从而允许我们重写该事件并实现所需的效果。

您可以从 这里获取正确版本的 Framework。

工作原理

我为其中包含的代码所做的贡献微乎其微,因为这种“方法”的许多部分都可以在网上轻易找到。对我(至少对我而言)来说,最困难的部分是将它们整合到一个可重用且灵活的方法中,以提供控件的proper formatting。

基本方法是构建一个继承自 DataGridTextBoxColumn 的类,然后将其应用于网格的表样式。该类包含三个重要元素:一个包含列号的属性,一些(1个或多个)事件,以及对 Paint 事件的重写。

事件是稍微自定义过的;我们使用一个继承自 EventArgs 的简单类,该类允许事件的结果包含行、列和一个布尔值。

基本计划是从 Paint 事件中发出一个事件,等待 DataGridEnableEventArgs 类型的返回结果。我们检查布尔属性(我称之为 meetsCriteria),然后相应地“绘制”单元格。

下面的代码显示了一个简单版本。CheckCellEven 是我们的事件之一;我们首先检查它是否不为 null(针对 ColumnStyle),如果不是,则触发事件。事件返回一个布尔值(基于订阅事件中的某些逻辑),在这种情况下,我们更改 BackBrush 颜色,但我们可以完全访问 graphics canvas,并像在任何其他 Paint 事件中一样绘制线条、字符串等。

protected override void Paint(Graphics g, Rectangle Bounds, CurrencyManager Source, 
                   int RowNum, Brush BackBrush, Brush ForeBrush, bool AlignToRight)
{
    if (CheckCellEven != null)
    {
        DataGridEnableEventArgs e = new DataGridEnableEventArgs
                (RowNum, _col, enabled);
        CheckCellEven(this, e);
        if (e.MeetsCriteria)
            BackBrush = new SolidBrush(Color.Orange);
    }

    base.Paint(g, Bounds, Source, RowNum, BackBrush, ForeBrush, AlignToRight);
}

这是一种简单的实现方式,可以对单个单元格应用多种格式化样式。订阅事件可以位于包含 DataGrid 的同一个类中,因此可以完全访问 DataGrid 本身以及任何其他控件或变量。这使得几乎无限的逻辑可用于确定如何以特定方式绘制每个单元格。

Using the Code

在网格控件用数据填充后(在本例中,数据来自 SDK Northwind 示例),其使用方式与本文无关。

接下来,我们为 DataSet 中的每一列实例化一个 ColumnStyle 类。我包含了几种确定哪些列触发哪些事件订阅的方法,以及几种事件可以确定结果的方法。

请记住,我们的 ColumnStyle 类继承自 DataGridTextBoxColumn,因此我们将该类的每个实例添加到 DataGridTableStyle 类的实例中,然后再将 DataGridTableStyle 添加到 DataGrid.Tables.Styles

我使用了一个匿名方法来连接事件,这值得一看。

在下面的代码中,我们检查 DataTable.Column 并检查其数据类型;如果它是 int,我们使用匿名方法和 delegate 添加事件处理程序。在这种情况下,我们只检查我们正在绘制的单元格是否包含值 2。

if (dt.Columns[i].DataType == System.Type.GetType("System.Int32"))
    myStyle.CheckCellEquals += 
      delegate(object sender, DataGridEnableEventArgs e)
      {
        e.MeetsCriteria = ((int)dataGrid1[e.Row, e.Column] == 2) ? 
        true : false;
      };

并非最终示例

在有人抱怨之前,此示例旨在展示一种我发现难以实现的方法。对发生的任何转换都没有进行错误检查,如果您使用不同的数据,它远非健壮。该方法可以在使用 DataGrid 的任何场景中工作,并且可以进行扩展以构建非常复杂的网格。

不要被下载的大小吓倒,其中主要是 Northwind 数据库,因为我不想花时间填充网格控件,这是最简单的方法。实际代码包含在两个文件中,仅包含三个类和几个方法,实现非常简单。

这只是一个我想要整合起来展示这种方法的简单示例。它将不再进一步开发。

历史

  • 2007 年 8 月 29 日:首次发布。
© . All rights reserved.