Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Depends4Net - Part 2

0.00/5 (No votes)
30 Aug 2011 2  
A .NET 2.0 Windows Forms based version of Depends4Net - Shows how to create custom datasources for databinding

Introduction

While the version of Depends4Net I presented in the previous part of this series works well enough when you have .NET 4.0 installed on the target system, there are times when .NET 4.0 is not available – so here is the .NET 2.0 version of the utility.

Be aware that it will not be happy about .NET 4.0 assemblies, but it has no problems with .NET 3.0 and 3.5 …

1Depends4Net2WinForm600.png

While Windows Forms programming has been dealt with in several very good articles here on CodeProject – there is one piece generally missing from the puzzle: An easy to use component for binding to a collection of custom data types.

Creating a Custom datasource for Windows Forms databinding

As usual, when you want to create something in .NET, it pays off to examine what’s already there, and as I like to do my Windows Forms development using the visual designer, I must present the framework with something it knows how to handle.

2Depends4Net2WinFormComponents300.png

In this case, assemblyDataList is an instance of AssemblyDataList and assemblyBindingSource is an instance of our well known friend System.Windows.Forms.BindingSource. I want to be able to configure the BindingSource using the visual design in the usual way:

3assemblyBindingSource400.png

And it should also be fairly easy to implement new components that expose collections of custom types to Windows Forms databinding. The complete source code for AssemblyDataList looks like this:

public class AssemblyDataList : BindingComponent<AssemblyData>
{
}

That doesn’t look too hard, so I’m pretty happy about the generic BindingComponent<T> class.

The generic BindingComponent<T> obviously needs to be derived from System.ComponentModel.Component to be supported by the designer, and it needs to implement the ITypedList interface to provide BindingSource with the information it needs to facilitate databinding. .NET also provides a generic BindingList<T> class that suits my purpose.

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;
        }
    }

As IBindingList requires me to implement the “event ListChangedEventHandler ListChanged;”, I just implement it by wrapping the event on the BindingList<T>, and implement the rest of the IBindingList interface by wrapping the functionality of the BindingList<T> class. So basically BindingComponent<T> is a component that wraps BindingList<T>.

ITypedList requires me to implement two methods; GetItemProperties that returns a PropertyDescriptorCollection and GetListName that returns the name of the list as a string, and it turns out that .NET provides a ready to use reusable implantation in the form of the System.Windows.Forms.ListBindingHelper class.

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;
    }
}

So .NET provides me with all I need to easily implement the generic BindingComponent<T> class.

Concluding Remarks

Creating custom components that facilitate binding to collections of data is, as you can see, really easy to implement. I usually expose data from the business model of my applications using similar techniques – and this makes it easy for other developers to rapidly create user interfaces where little or sometimes no coding is required.

4ComponentInToolbox300.png

Just drag the component from the Toolbox onto the form, and use the tools provided with Visual Studio to rapidly create fairly complex Windows Forms based user interfaces.

What’s Next

Originally I wanted to use the WPF DataGrid, but “ExpressionDark.xaml” does not contain a style for the DataGrid. A preview of an “ExpressionDark” style for the DataGrid is now included with the “Harlinn.Depends4Net” project included with the download.

5Depends4NetPart3Preview600.png

The next article will tackle styling of the DataGrid – and I expect the result will improve the look of the application.

History

  • 30th August, 2011 - Initial posting

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here