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

Depends4Net -第二部分

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (12投票s)

2011年8月30日

CPOL

3分钟阅读

viewsIcon

28070

downloadIcon

807

基于 .NET 2.0 Windows Forms 的 Depends4Net 版本 - 展示如何为数据绑定创建自定义数据源

引言

虽然我在本系列前一部分中介绍的 Depends4Net 版本在目标系统上安装了 .NET 4.0 时运行良好,但有时 .NET 4.0 不可用 – 所以这里是该实用程序的 .NET 2.0 版本。

请注意,它对 .NET 4.0 程序集不满意,但它对 .NET 3.0 和 3.5 没有问题……

1Depends4Net2WinForm600.png

虽然 CodeProject 上已经有很多关于 Windows Forms 编程的优秀文章 – 但拼图中通常缺少一块:一个易于使用的组件,用于绑定到自定义数据类型的集合。

为 Windows Forms 数据绑定创建自定义数据源

通常,当您想在 .NET 中创建某些内容时,查看已有的内容是有好处的,并且由于我喜欢使用可视化设计器进行 Windows Forms 开发,因此我必须向框架提供它知道如何处理的东西。

2Depends4Net2WinFormComponents300.png

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

3assemblyBindingSource400.png

并且也应该很容易实现新的组件,这些组件将自定义类型的集合公开给 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> 类所需的一切。

结论

创建方便绑定到数据集合的自定义组件,正如您所看到的,很容易实现。我通常使用类似的技术从应用程序的业务模型中公开数据 – 这使得其他开发人员可以快速创建用户界面,而几乎不需要甚至不需要编码。

4ComponentInToolbox300.png

只需将组件从工具箱拖到窗体上,然后使用 Visual Studio 提供的工具快速创建相当复杂的基于 Windows Forms 的用户界面。

下一步

最初我想使用 WPF DataGrid,但是“ExpressionDark.xaml”不包含 DataGrid 的样式。 现在,下载中包含的 “Harlinn.Depends4Net” 项目包含 DataGrid 的 “ExpressionDark” 样式预览。

5Depends4NetPart3Preview600.png

下一篇文章将探讨 DataGrid 的样式设置 – 我希望结果能够改善应用程序的外观。

历史

  • 2011 年 8 月 30 日 – 首次发布
© . All rights reserved.