77、数据网格控件的使用与定制

数据网格控件的使用与定制

1. 列的调整大小和重新排列

当显示自动生成的列时,数据网格(DataGrid)会智能地调整每列的宽度。初始时,每列的宽度刚好能显示当前可见的最大值(如果标题更宽,则以标题宽度为准)。当用户滚动数据时,DataGrid 会尽力保持这种智能的大小调整方式。一旦遇到包含更长数据的行,DataGrid 会自动加宽相应的列以适应数据。不过,这种自动调整大小是单向的,即当离开包含大数据的行时,列不会缩小。

自动调整列宽虽然有趣且通常很有用,但并非总是符合需求。例如,若有一个包含长文本字符串的“Description”列,初始时该列会变得极宽,从而挤压其他列的空间。在列被手动调整大小后,用户滚动数据时它不会再自动放大。

为避免用户面对过宽的列,可通过显式定义列来正确设置列宽。通常,用户可通过拖动列边缘来调整列宽。若要阻止用户调整 DataGrid 中的列宽,可将 CanUserResizeColumns 属性设置为 False ;若要阻止用户调整某一特定列的宽度,可将该列的 CanUserResize 属性设置为 False ;还可通过设置列的 MinWidth 属性来防止用户将列缩得过窄。

此外,DataGrid 允许用户重新排列列。若不希望用户有此功能,可将 DataGrid 的 CanUserReorderColumns 属性或特定列的 CanUserReorder 属性设置为 False

2. 定义列

使用自动生成的列可快速创建一个显示所有数据的 DataGrid,但会失去一些控制权,如无法控制列的顺序、宽度、值的格式以及标题文本。更强大的方法是将 AutoGenerateColumns 设置为 False 以关闭自动列生成,然后显式定义所需的列及其设置和顺序。为此,需将正确的列对象填充到 DataGrid.Columns 集合中。

目前,DataGrid 支持三种类型的列,由继承自 DataGridColumn 的三个不同类表示:
- DataGridTextColumn :适用于大多数数据类型。值会转换为文本并显示在 TextBlock 中,编辑行时, TextBlock 会被标准文本框替换。
- DataGridCheckBoxColumn :显示一个复选框,自动用于布尔(或可空布尔)值。通常,复选框为只读,编辑行时变为普通复选框。
- DataGridTemplateColumn :功能最强大,允许定义数据模板来显示列值,具有与列表控件中使用模板相同的灵活性和功能,可用于显示图像数据或使用专门的 Silverlight 控件。

以下是一个创建包含产品名称和价格两列显示的 DataGrid 示例:

<data:DataGrid x:Name="gridProducts" Margin="5" AutoGenerateColumns="False">
  <data:DataGrid.Columns>
    <data:DataGridTextColumn Header="Product" Width="175" 
     Binding="{Binding ModelName}"></data:DataGridTextColumn>
    <data:DataGridTextColumn Header="Price" 
     Binding="{Binding UnitCost}"></data:DataGridTextColumn>
  </data:DataGrid.Columns>
</data:DataGrid>

定义列时,通常需设置三个细节:列顶部显示的标题文本、列的宽度以及获取数据的绑定。DataGrid 的数据绑定方法与大多数其他列表控件不同,其 Binding 方法更灵活,允许在不使用完整模板列的情况下合并值转换器。例如,可使用绑定的 StringFormat 属性将 UnitCost 列格式化为货币值:

<data:DataGridTextColumn Header="Price" Binding=
 "{Binding UnitCost, StringFormat='C'}">
</data:DataGridTextColumn>

还可通过修改相应列对象的 Visibility 属性动态显示和隐藏列,通过更改 DisplayIndex 值随时移动列。

3. DataGridCheckBoxColumn

Product 类包含布尔属性, DataGridCheckBoxColumn 会是一个有用的选项。与 DataGridTextColumn 一样, Binding 属性提取数据,用于设置内部 CheckBox 元素的 IsChecked 属性。此外, DataGridCheckBoxColumn 还添加了 Content 属性,可在复选框旁边显示可选内容,以及 IsThreeState 属性,用于确定复选框是否支持未确定状态。若使用该列显示可空布尔值的信息,可将 IsThreeState 属性设置为 True ,使用户能点击回到未确定状态。

4. DataGridTemplateColumn

DataGridTemplateColumn 使用数据模板,其工作方式与之前在列表控件中探索的数据模板功能相同。不同之处在于,它允许定义两个模板:一个用于数据显示( CellTemplate ),一个用于数据编辑( CellEditingTemplate )。以下是一个使用模板数据列在网格中放置每个产品缩略图的示例:

<data:DataGridTemplateColumn>
  <data:DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
      <Image Stretch="None" Source=
       "{Binding ProductImagePath, Converter={StaticResource ImagePathConverter}}">
      </Image>
    </DataTemplate>
  </data:DataGridTemplateColumn.CellTemplate>
</data:DataGridTemplateColumn>

此示例假设已将 ImagePathConverter 值转换器添加到 UserControl.Resources 集合中:

<UserControl.Resources>
  <local:ImagePathConverter x:Key="ImagePathConverter"></local:ImagePathConverter>
</UserControl.Resources>
5. 列的格式化和样式设置

可通过设置 Foreground FontFamily FontSize FontStyle FontWeight 属性,以与格式化 TextBlock 元素相同的方式格式化 DataGridTextColumn 。但该列未公开 TextBlock 的所有属性,例如,若要创建显示多行文本的列,无法设置常用的 Wrapping 属性,此时需使用 ElementStyle 属性。

ElementStyle 属性允许创建应用于 DataGrid 单元格内元素的样式。对于简单的 DataGridTextColumn ,该元素是 TextBlock ;对于 DataGridCheckBoxColumn ,是复选框;对于 DataGridTemplateColumn ,则是在数据模板中创建的元素。以下是一个允许列中文本换行的简单样式示例:

<data:DataGridTextColumn Header="Description" Width="400" 
 Binding="{Binding Description}">
  <data:DataGridTextColumn.ElementStyle>
    <Style TargetType="TextBlock">
      <Setter Property="TextWrapping" Value="Wrap"></Setter>
    </Style>
  </data:DataGridTextColumn.ElementStyle>
</data:DataGridTextColumn>

要查看换行后的文本,需扩展行高。由于 DataGrid 无法像 Silverlight 布局容器那样灵活调整自身大小,因此需使用 DataGrid.RowHeight 属性设置固定的行高,该高度适用于所有行。

还可使用 EditingElementStyle 来设置编辑列时使用的元素的样式。 ElementStyle ElementEditingStyle 和列属性可用于格式化特定列中的所有单元格。若要对每列的每个单元格应用格式化设置,最简单的方法是为 DataGrid.RowStyle 属性配置样式。此外,DataGrid 还公开了一组额外的属性,用于格式化网格的其他部分,如下表所示:
| 属性 | 样式应用于… |
| ---- | ---- |
| ColumnHeaderStyle | 网格顶部用于列标题的 TextBlock |
| RowHeaderStyle | 用于行标题的 TextBlock |
| CornerHeaderStyle | 行标题和列标题之间的角单元格 |
| RowStyle | 普通行(未通过列的 ElementStyle 属性专门定制的列中的行)使用的 TextBlock |

6. 控制列宽

设置列的初始大小时,可设置其 Width 属性,有三种基本选择:
- 固定大小 :将 Width 属性设置为像素数,如 200
- 自动大小 :将 Width 属性设置为以下三个特殊值之一: SizeToCells (加宽以匹配最大显示单元格值)、 SizeToHeader (加宽以匹配标题文本)或 Auto (加宽以匹配最大显示单元格值或标题,取较大者)。使用 SizeToCells Auto 时,滚动时列可能会加宽。若未设置 Width 属性,列将使用 DataGrid.ColumnWidth 属性的值,默认值为 Auto
- 比例大小 :将 Width 属性设置为星号 * ,此方法类似于 Grid 布局容器的比例大小调整。所有固定大小和自动大小的列设置好后,剩余空间将在比例列之间分配。若要让某些列获得更多自由空间,可设置带数字和星号的值,如 2* 的列将获得 * 列两倍的空间。

以下是一个示例,其中一列使用固定宽度,一列使用自动大小,另外两列使用比例大小:

<data:DataGrid.Columns>
  <data:DataGridTextColumn Header="Model Number" Binding="{Binding ModelNumber}" 
   Width="100"></data:DataGridTextColumn>
  <data:DataGridTextColumn Header="Model Name" Width="100" 
   Binding="{Binding ModelName}"></data:DataGridTextColumn>
  <data:DataGridTextColumn Header="Unit Cost" Width="*" MinWidth="50" 
   Binding="{Binding UnitCost, StringFormat='C'}"></data:DataGridTextColumn>
  <data:DataGridTextColumn Width="2*" MinWidth="50" 
   Binding="{Binding Description}" Header="Description" >
    <data:DataGridTextColumn.ElementStyle>
      <Style TargetType="TextBlock">
        <Setter Property="TextWrapping" Value="Wrap"></Setter>
      </Style>
    </data:DataGridTextColumn.ElementStyle>
  </data:DataGridTextColumn>
</data:DataGrid.Columns>

比例大小调整的好处是可创建适应可用空间的网格。只要添加一个比例大小的列, GridView 就会移除水平滚动条。当调整 GridView 大小时,它会相应地调整列的大小。若将 GridView 调大,比例大小的列将获得所有额外空间;若调小,这些列的空间会逐渐减少,直到达到其 MinWidth 值。若继续缩小,其他列也会从其原始固定或自动大小开始缩小,直到达到其 MinWidth 值;若所有列都达到最小宽度后仍继续缩小, GridView 会继续将列宽缩小到 MinWidth 设置以下,直到所有列都折叠。

7. 行的格式化

通过设置 DataGrid 列对象的属性,可控制整列的格式。但在许多情况下,标记包含特定数据的行更有用,例如突出显示高价产品或过期发货。可通过处理 DataGrid.LoadingRow 事件以编程方式应用此类格式。

LoadingRow 事件是行格式化的强大工具,它可访问当前行的数据对象,允许执行简单范围检查、比较和更复杂的操作,还提供行的 DataGridRow 对象,可使用不同颜色或字体格式化行。但无法仅格式化该行中的单个单元格,为此需要 DataGridTemplateColumn IValueConverter

该事件在每行出现在屏幕上时触发一次。优点是应用程序无需格式化整个网格,仅对当前可见的行触发;缺点是用户滚动网格时,该事件会持续触发,因此不能在 LoadingRow 方法中放置耗时的代码,否则滚动会变慢。

此外,还需考虑虚拟化。为降低内存开销,DataGrid 在滚动数据时会重用相同的 DataGrid 对象来显示新数据,因此要确保将每行恢复到初始状态,以防止将数据加载到已格式化的 DataGridRow 中。

以下是一个示例,将高价物品的背景设置为亮橙色,普通价格物品的背景设置为标准白色:

' Reuse brush objects for efficiency in large data displays.
Private highlightBrush As New SolidColorBrush(Colors.Orange)
Private normalBrush As New SolidColorBrush(Colors.White)

Private Sub gridProducts_LoadingRow(ByVal sender As Object, _
  ByVal e As DataGridRowEventArgs)
    ' Check the data object for this row.
    Dim product As Product = CType(e.Row.DataContext, Product)

    ' Apply the conditional formatting.
    If product.UnitCost > 100 Then
        e.Row.Background = highlightBrush
    Else
        ' Restore the default white background. This ensures that used,
        ' formatted DataGrid object are reset to their original appearance.
        e.Row.Background = normalBrush
    End If
End Sub

另一种基于值的格式化方法是使用 IValueConverter 检查绑定数据并将其转换为其他内容,结合 DataGridTemplateColumn 时此技术尤其强大,可仅格式化包含价格的单元格,而非整行。

8. 行详细信息

DataGrid 支持行详细信息,这是一个可选的单独显示区域,出现在行的列值下方。行详细信息区域有两个优点:一是跨越 DataGrid 的整个宽度,不分割成单独的列,提供更多操作空间;二是可配置为仅在选中行时显示,不使用时可隐藏额外细节。

要创建包含行详细信息的示例,需先设置 DataGrid.RowDetailsTemplate 属性来定义行详细信息区域显示的内容。例如,以下模板包含一个显示完整产品文本并添加边框的 TextBlock

<data:DataGrid.RowDetailsTemplate>
  <DataTemplate>
    <Border>
      <Border Margin="10" Padding="10" BorderBrush="SteelBlue" BorderThickness="3" 
       CornerRadius="5">
        <TextBlock Text="{Binding Description}" TextWrapping="Wrap" FontSize="10">
        </TextBlock>
      </Border>
    </Border>
  </DataTemplate>
</data:DataGrid.RowDetailsTemplate>

还可在行详细信息区域添加控件以执行各种任务。需注意,DataGrid 调整行详细信息区域大小时不考虑根元素的边距,可能导致内容被裁剪。可添加额外容器来解决此问题。

可通过设置 DataGrid.RowDetailsVisibilityMode 属性来配置行详细信息区域的显示行为。默认值为 VisibleWhenSelected ,表示仅在选中行时显示;也可设置为 Visible 以显示所有行的详细信息,或设置为 Collapsed 隐藏所有行的详细信息,后续可在代码中更改该属性。

9. 冻结列

冻结列在滚动到右侧时会固定在 DataGrid 的左侧。例如,将“Product”列冻结后,滚动时该列仍保持可见,且水平滚动条仅在可滚动列下方延伸。

列冻结功能对于非常宽的网格很有用,可确保某些信息(如产品名称或唯一标识符)始终可见。要使用此功能,将列的 IsFrozen 属性设置为 True ,示例如下:

<data:DataGridTextColumn Header="Product" Width="175" IsFrozen="True" 
 Binding="{Binding ModelName}"></data:DataGridTextColumn>

通过以上方法,可充分利用 DataGrid 的各种功能,实现灵活的数据显示和定制。

数据网格控件的使用与定制

10. 综合应用示例

为了更好地展示上述各项功能的综合应用,下面给出一个完整的示例。假设我们有一个产品列表,包含产品名称、价格、描述和是否有库存等信息,我们将使用 DataGrid 来展示这些数据,并应用前面提到的各种定制功能。

<data:DataGrid x:Name="gridProducts" Margin="5" AutoGenerateColumns="False"
               CanUserResizeColumns="True" CanUserReorderColumns="True"
               RowHeight="70" ColumnWidth="Auto">
    <data:DataGrid.Columns>
        <data:DataGridTextColumn Header="Product" Width="175" IsFrozen="True"
                                 Binding="{Binding ModelName}">
        </data:DataGridTextColumn>
        <data:DataGridTextColumn Header="Price" Binding="{Binding UnitCost, StringFormat='C'}"
                                 Width="Auto">
        </data:DataGridTextColumn>
        <data:DataGridTextColumn Header="Description" Width="400"
                                 Binding="{Binding Description}">
            <data:DataGridTextColumn.ElementStyle>
                <Style TargetType="TextBlock">
                    <Setter Property="TextWrapping" Value="Wrap"></Setter>
                </Style>
            </data:DataGridTextColumn.ElementStyle>
        </data:DataGridTextColumn>
        <data:DataGridCheckBoxColumn Header="In Stock" Binding="{Binding IsInStock}"
                                     Content="Available" IsThreeState="False">
        </data:DataGridCheckBoxColumn>
    </data:DataGrid.Columns>
    <data:DataGrid.RowDetailsTemplate>
        <DataTemplate>
            <Border>
                <Border Margin="10" Padding="10" BorderBrush="SteelBlue" BorderThickness="3"
                        CornerRadius="5">
                    <TextBlock Text="{Binding AdditionalInfo}" TextWrapping="Wrap" FontSize="10">
                    </TextBlock>
                </Border>
            </Border>
        </DataTemplate>
    </data:DataGrid.RowDetailsTemplate>
    <data:DataGrid.RowStyle>
        <Style TargetType="DataGridRow">
            <EventSetter Event="LoadingRow" Handler="gridProducts_LoadingRow"></EventSetter>
        </Style>
    </data:DataGrid.RowStyle>
</data:DataGrid>
' Reuse brush objects for efficiency in large data displays.
Private highlightBrush As New SolidColorBrush(Colors.Orange)
Private normalBrush As New SolidColorBrush(Colors.White)

Private Sub gridProducts_LoadingRow(ByVal sender As Object, _
  ByVal e As DataGridRowEventArgs)
    ' Check the data object for this row.
    Dim product As Product = CType(e.Row.DataContext, Product)

    ' Apply the conditional formatting.
    If product.UnitCost > 100 Then
        e.Row.Background = highlightBrush
    Else
        ' Restore the default white background. This ensures that used,
        ' formatted DataGrid object are reset to their original appearance.
        e.Row.Background = normalBrush
    End If
End Sub

在这个示例中:
- 我们关闭了自动列生成,显式定义了四列,包括产品名称、价格、描述和是否有库存。
- 产品名称列被冻结,确保滚动时始终可见。
- 价格列使用了货币格式。
- 描述列设置了文本换行样式。
- 库存列使用了 DataGridCheckBoxColumn 来显示布尔值。
- 行详细信息区域显示了产品的额外信息。
- 通过 LoadingRow 事件对高价产品的行背景进行了高亮显示。

11. 性能考虑

在使用 DataGrid 时,性能是一个需要关注的重要方面。以下是一些性能优化的建议:
- 减少不必要的自动调整 :自动调整列宽在某些情况下可能会导致性能下降,尤其是在数据量较大时。如果不需要自动调整列宽,可使用固定大小或比例大小的列。
- 避免在 LoadingRow 事件中进行耗时操作 :如前面所述, LoadingRow 事件在滚动时会频繁触发,因此应避免在其中放置耗时的代码,以免影响滚动性能。
- 合理使用虚拟化 :DataGrid 本身支持虚拟化,可有效降低内存开销。确保在大数据集的情况下充分利用这一特性。

12. 总结

DataGrid 是一个功能强大的数据显示控件,提供了丰富的定制选项,可满足各种不同的需求。通过显式定义列、控制列宽、格式化行和列、添加行详细信息以及冻结列等功能,我们可以创建出高度定制化的数据网格。

同时,在使用过程中需要注意性能问题,合理配置各项属性和事件处理程序,以确保应用程序的流畅运行。希望通过本文的介绍,你能更好地掌握 DataGrid 的使用和定制技巧,在实际项目中发挥其最大的作用。

以下是一个总结 DataGrid 主要定制功能的表格:
| 定制功能 | 实现方法 |
| ---- | ---- |
| 列调整大小和重新排列 | 设置 CanUserResizeColumns CanUserReorderColumns 等属性 |
| 定义列 | 设置 AutoGenerateColumns False ,并填充 DataGrid.Columns 集合 |
| 列格式化和样式设置 | 使用 ElementStyle EditingElementStyle 等属性 |
| 控制列宽 | 设置 Width 属性为固定值、自动值或比例值 |
| 行格式化 | 处理 DataGrid.LoadingRow 事件 |
| 行详细信息 | 设置 DataGrid.RowDetailsTemplate DataGrid.RowDetailsVisibilityMode 属性 |
| 冻结列 | 设置列的 IsFrozen 属性为 True |

下面是一个简单的 mermaid 流程图,展示了使用 DataGrid 的基本步骤:

graph TD;
    A[创建 DataGrid] --> B[关闭自动列生成];
    B --> C[定义列];
    C --> D[设置列属性和样式];
    D --> E[设置行属性和样式];
    E --> F[添加行详细信息];
    F --> G[应用定制功能(如冻结列)];
    G --> H[处理事件(如 `LoadingRow`)];

通过以上步骤和定制功能,你可以创建出满足各种需求的数据网格控件。

潮汐研究作为海洋科学的关键分支,融合了物理海洋学、地理信息系统及水利工程等多领域知识。TMD2.05.zip是一套基于MATLAB环境开发的潮汐专用分析工具集,为科研人员工程实践者提供系统化的潮汐建模计算支持。该工具箱通过模块化设计实现了两大核心功能: 在交互界面设计方面,工具箱构建了图形化操作环境,有效降低了非专业用户的操作门槛。通过预设参数输入模块(涵盖地理坐标、时间序、测站数据等),用户可自主配置模型运行条件。界面集成数据加载、参数调整、可视化呈现及流程控制等标准化组件,将复杂的数值运算过程转化为可交互的操作流程。 在潮汐预测模块中,工具箱整合了谐波分解法潮流要素解析法等数学模型。这些算法能够解构潮汐观测数据,识别关键影响要素(包括K1、O1、M2等核心分潮),并生成不同时间尺度的潮汐预报。基于这些模型,研究者可精准推算特定海域的潮位变化周期振幅特征,为海洋工程建设、港湾规划设计及海洋生态研究提供定量依据。 该工具集在实践中的应用方向包括: - **潮汐动力解析**:通过多站点观测数据比对,揭示区域主导潮汐成分的时空分布规律 - **数值模型构建**:基于历史观测序建立潮汐动力学模型,实现潮汐现象的数字化重构预测 - **工程影响量化**:在海岸开发项目中评估人工构筑物对自然潮汐节律的扰动效应 - **极端事件模拟**:建立风暴潮天文潮耦合模型,提升海洋灾害预警的时空精度 工具箱以"TMD"为主程序包,内含完整的函数库示例脚本。用户部署后可通过MATLAB平台调用相关模块,参照技术文档完成全流程操作。这套工具集将专业计算能力人性化操作界面有机结合,形成了从数据输入到成果输出的完整研究链条,显著提升了潮汐研究的工程适用性科研效率。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值