Depends4Net -第二部分






4.83/5 (12投票s)
基于 .NET 2.0 Windows Forms 的 Depends4Net 版本 - 展示如何为数据绑定创建自定义数据源
引言
虽然我在本系列前一部分中介绍的 Depends4Net 版本在目标系统上安装了 .NET 4.0 时运行良好,但有时 .NET 4.0 不可用 – 所以这里是该实用程序的 .NET 2.0 版本。
请注意,它对 .NET 4.0 程序集不满意,但它对 .NET 3.0 和 3.5 没有问题……

虽然 CodeProject 上已经有很多关于 Windows Forms 编程的优秀文章 – 但拼图中通常缺少一块:一个易于使用的组件,用于绑定到自定义数据类型的集合。
为 Windows Forms 数据绑定创建自定义数据源
通常,当您想在 .NET 中创建某些内容时,查看已有的内容是有好处的,并且由于我喜欢使用可视化设计器进行 Windows Forms 开发,因此我必须向框架提供它知道如何处理的东西。

在这种情况下,assemblyDataList
是 AssemblyDataList
的一个实例,而 assemblyBindingSource
是我们熟知的朋友 System.Windows.Forms.BindingSource
的一个实例。 我希望能够以通常的方式使用视觉设计配置 BindingSource
。

并且也应该很容易实现新的组件,这些组件将自定义类型的集合公开给 Windows Forms 数据绑定。 AssemblyDataList
的完整源代码如下所示
public class AssemblyDataList : BindingComponent<AssemblyData>
{
}
看起来不太难,所以我对通用的 BindingComponent<T>
类感到非常满意。
通用的 BindingComponent<T>
显然需要从 System.ComponentModel.Component
派生才能被设计器支持,并且它需要实现 ITypedList
接口,以便为 BindingSource
提供它需要的信息以方便数据绑定。.NET 还提供了一个通用的 BindingList<T>
类,它适合我的目的。
public class BindingComponent<T> : Component, IBindingList, ITypedList
{
BindingList<T> items;
public event ListChangedEventHandler ListChanged;
public BindingComponent()
{
items = new BindingList<T>();
items.ListChanged += items_ListChanged;
}
void items_ListChanged(object sender, ListChangedEventArgs e)
{
if (ListChanged != null)
{
ListChanged(this, e);
}
}
protected override void Dispose(bool disposing)
{
items.ListChanged -= items_ListChanged;
base.Dispose(disposing);
}
[ListBindable(true)]
[Bindable(true)]
[Browsable(true)]
public BindingList<T> Items
{
get
{
return items;
}
}
由于 IBindingList
要求我实现“event ListChangedEventHandler ListChanged;
”,我只是通过包装 BindingList<T>
上的事件来实现它,并通过包装 BindingList<T>
类的功能来实现 IBindingList
接口的其余部分。所以基本上 BindingComponent<T>
是一个包装 BindingList<T>
的组件。
ITypedList
要求我实现两个方法;GetItemProperties
,它返回一个 PropertyDescriptorCollection
,和 GetListName
,它返回列表的名称作为 string
,并且事实证明 .NET 以 System.Windows.Forms.ListBindingHelper
类的形式提供了一个随时可用的可重用实现。
private PropertyDescriptorCollection propertyDescriptorCollection;
public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors)
{
if (listAccessors != null && listAccessors.Length > 0)
{
PropertyDescriptorCollection result =
ListBindingHelper.GetListItemProperties(items, listAccessors);
return result;
}
else
{
if (propertyDescriptorCollection == null)
{
propertyDescriptorCollection =
TypeDescriptor.GetProperties(typeof(T), new Attribute[]
{ new BrowsableAttribute(true) });
}
return propertyDescriptorCollection;
}
}
public string GetListName(PropertyDescriptor[] listAccessors)
{
if (listAccessors != null && listAccessors.Length > 0)
{
return ListBindingHelper.GetListName(items, listAccessors);
}
else
{
return typeof(T).Name;
}
}
因此 .NET 为我提供了轻松实现通用 BindingComponent<T>
类所需的一切。
结论
创建方便绑定到数据集合的自定义组件,正如您所看到的,很容易实现。我通常使用类似的技术从应用程序的业务模型中公开数据 – 这使得其他开发人员可以快速创建用户界面,而几乎不需要甚至不需要编码。

只需将组件从工具箱拖到窗体上,然后使用 Visual Studio 提供的工具快速创建相当复杂的基于 Windows Forms 的用户界面。
下一步
最初我想使用 WPF DataGrid
,但是“ExpressionDark.xaml”不包含 DataGrid
的样式。 现在,下载中包含的 “Harlinn.Depends4Net
” 项目包含 DataGrid
的 “ExpressionDark
” 样式预览。

下一篇文章将探讨 DataGrid
的样式设置 – 我希望结果能够改善应用程序的外观。
历史
- 2011 年 8 月 30 日 – 首次发布