在 WPF DataGrid 中嵌入控件
示例程序演示了如何使用VB.NET在WPF DataGrid中嵌入控件。
引言
WPF的ListView
和 DataGrid
控件非常强大,但在VB.NET(VS 2010 Beta 1)中不使用XAML进行编程却相当神秘。本文展示了如何将各种控件嵌入ListView
和 DataGrid
的单元格中。示例程序演示了如何嵌入TextBlock
、TextBox
、FlowDocument
和 RichTextBox
。演示程序的数据源是一个LINQ查询,用于获取进程信息(进程名、ID等)。网格可以通过LINQ查询直接或间接通过DataTable
s构建。数据绑定、控件工厂、IValueConverter
和 INotifyPropertyChange
用于构建示例程序。演示程序提供了一个选项矩阵,用于生成各种数据源和数据类型的网格。
背景
在处理一个需要在一个网格中显示富文本的项目时,我对WPF DataGrid
控件缺乏信息感到非常沮丧。我想在代码(VB.NET,无XAML)中构建控件。很少有示例。因此,我决定创建一个大型示例程序,演示LINQ查询、控件和数据绑定的多种组合。
使用代码
附加的程序使用三种不同的方法来捕获LINQ查询。该查询使用GetProcess
来获取有关当前运行进程的信息。
- 将查询结果捕获为匿名类型。
- 将查询结果捕获为类(
ProcessInfo
)的实例。 - 使用上述方法创建一个集合类(
ProcessInfoCollection
),该类使用INotifyPropertyChange
来启用动态绑定。
用户可以选择上述任何或所有LINQ查询方法来创建绑定。该绑定可用于直接馈送ListView
或 DataGrid
控件,或间接通过从查询创建DataTable
s,然后绑定DataTable
s。 该程序允许用户创建九种数据类型的DataTable
s。
- 源数据类型。
DataTable
列从数据源继承其类型。 - 所有列均为
String
类型。 - 所有列均为
TextBlock
控件。TextBlock
s具有一定的富文本能力。 由于TextBlock
s不能使用FrameworkElementFactory
创建(它们缺少InlinesProperty
),因此程序包含BindableTextBlock
类,以允许FrameworkElementFactory
工作。 - 所有列均为
BindableTextBlock
s。 - 所有列均为
TextBox
es。TextBox
缺少富文本能力。 - 所有列均为
FlowDocument
的字符串表示形式。 - 所有列均为
FlowDocument
控件。 - 所有列均为
RichTextBox
控件。由于RichTextBox
es不能使用FrameworkElementFactory
创建(它们缺少DocumentProperty
),因此程序包含BindableRichTextBox
类,以允许FrameworkElementFactory
工作。 - 所有列均为
BindableRichTextBox
。
用户可以选择ListView
或 DataGrid
控件列的数据类型。本质上与上述选择相同。这意味着上述任何数据类型都可能需要转换为其他数据类型(例如,从TextBlock
转换为RichTextBox
)。所有这些组合都由IValueConverter
接口的Convert
方法处理。
为了演示如何为单个单元格设置样式,用户可以选择根据单元格内容(使用正则表达式)进行文本样式设置。例如,所有以字母b开头的进程名称将以粗体显示,以i开头的名称将以斜体显示,以r开头的字母将具有红色前景色,而包含u的进程将带有下划线。否则,在FrameworkElementFactory
代码中,所有单元格都将具有黑色前景色和浅灰色背景。
“刷新”按钮将导致网格中出现新数据,但仅限于当INotify
类直接馈送到ListView
或 DataGrid
(而不是通过DataTable
)时。
最后一个选项允许用户生成ListView
s和/或 DataGrid
s窗口。请注意,很容易在选项中迷失方向,从而生成数十个窗口,这会耗尽您计算机的CPU和内存。
要构建项目,只需创建一个新的VS 2010 WPF应用程序项目,然后粘贴/复制Window1.xaml.vb和Window1.xaml。无需添加任何引用。

关注点
该程序魔法的关键是IValueConverter
接口的Convert
方法。该方法包含了从多种类型(数据类型和控件)转换为其他类型的“魔法”。其他挑战包括动态绑定(INotifyPropertyChange
),如ProcessInfoCollection
类中实现的,列绑定以及支持三种类型的LINQ结果。
历史
- 2009年9月24日:版本0.1