views:

54

answers:

2

In the program we are working on, the user data is collected in UserControls which is data bound to a business entity using BindingSources.

I need to find all the BindingSources in a UserControl programatically.

Since a BindingSource source is not added to the UserControl's Controls collection, I cannot search in there.

Can this be done?

+2  A: 

BindingSource is a Component, not a Control, so indeed you can't find it in the Controls collection. However, when you add components with the designer, it creates a field named components of type IContainer and adds the components to it. The field is private, so you can only access it from the class in which it is declared (unless you use reflection).

I think the easiest way to achieve what you want is to add a GetBindingSources method to all your using controls :

public IEnumerable<BindingSource> GetBindingSources()
{
    return components.Components.OfType<BindingSource>();
}

Of course, it will work only for BindingSources created with the designer, not for those you create dynamically (unless you add them to the container)

Thomas Levesque
I have choose to use reflection, because I don't know any way in which I can use the WinForms designer from the VS on a class which does not directly derive from UserControl, and I needed this method to be accessible to all my UserControls.My solution was to make the UserControls implement an interface, IBusinessEntityEditorView, and create an extension method for that interface that gets all the BindingSources.
Emanuel
A: 

The biggest problem was to find a solution for my method to be available for all the UserControls and still be able to use the WinForms designer from Visual Studio.

Because I don't know any way of using the designer on a class that does not derive from UserControl, I have made an interface without any methods, IBusinessEntityEditorView, and an extension method that takes such a view, uses reflection to find the components field in which I search for my BindingSources:

public interface IBusinessEntityEditorViewBase
{
}

...

public static void EndEditOnBindingSources(this IBusinessEntityEditorViewBase view)
{
    UserControl userControl = view as UserControl;
    if (userControl == null) return;

    FieldInfo fi = userControl.GetType().GetField("components", BindingFlags.NonPublic | BindingFlags.Instance);
    if (fi != null)
    {
        object components = fi.GetValue(userControl);
        if (components != null)
        {
            IContainer container = components as IContainer;
            if (container != null)
            {
                foreach (var bindingSource in container.Components.OfType<BindingSource>())
                {
                    bindingSource.EndEdit();
                }
            }
        }
    }
}
Emanuel