views:

167

answers:

3

I have a class that implements properties in a specific way, to handle some custom requirements for our business logic system.

This "specific way" makes the properties non-operational in the context of data binding. Basically, if I drop an object of our class onto a form, data binding finds nothing on the object, and the property inspector for that object, though it lists the properties, doesn't allow me to edit them.

What I'm wondering is if there's an interface or similar that I can implement in my class that will report to the form designer what properties could be bound to, and that implements the custom code necessary to talk to the data binding system on behalf of my properties.

Note that I do not need to be able to edit the property values for my object in the property inspector, that was just an example of how non-functional the properties are. I just need the data binding support.

Is there such an interface, and if so, what is it?

Let's give a simple example.

Let's assume I have this class:

public class CustomDataBinding : Component
{
    private Dictionary<String, Object> _Properties = new Dictionary<String, Object>();

    public CustomDataBinding()
    {
        _Properties["Property1"] = 10;
        _Properties["Property2"] = "Test";
    }
}

Is there anything I could do to my object, short of actually making the properties, that would add data binding support for those two "properties"?

Note that for my real class, I know the type of every property, so if it makes it easier, change the above code to just use string values:

public class CustomDataBinding : Component
{
    private Dictionary<String, String> _Properties = new Dictionary<String, String>();

    public CustomDataBinding()
    {
        _Properties["Property1"] = "Property1";
        _Properties["Property2"] = "Property2";
    }
}

I will also need validation support, as our class can report validation status for every property as well, but I have already implemented IDataErrorInfo and IDataValidationInfo which I think will give me that. I have also implemented INotifyPropertyChanged, so I got the change mechanism in place I think, but I need to discover and talk to the properties. Beyond those interfaces, anything else I should look into would be welcome information.

+1  A: 

You could always expose the Dictionary as a property and access elements of it directly (though it'd need to be by index and implement IListSource or IEnumerable.

-- Edit

I must say, though, you're effectively making your own untyped language. Interested in the reason for this, perhaps there is a better way ...

Noon Silk
+1  A: 

Since you can't publish new properties, how about publishing your Dictionary as an ObservableDictionary<string, object>. See this DrWPF article.

You could then bind to the dictionary using the key to get the named property you're after.

Ray Hayes
Definitely worth looking into, but for now the answer by Marc looks the most promising.
Lasse V. Karlsen
+4  A: 

It sounds like you are describing a property-bag; this is indeed supported for data-binding, but you need to implement ICustomTypeDescriptor or TypeDescriptionProvider. The available properties are then defined via TypeDescriptor.GetProperties(obj) or TypeDescriptor.GetProperties(type) - or in the case of lists, via ITypedList. ICustomTypeDescriptor is suitable if the properties change per-instance; TypeDescriptionProvider can do per-type customisation, and works with things like BindingList<T> without any extra work.

The tricky thing is that you need to define the type of each property - not simple if you've just got object. Here is a very simplified example, that treats all properties as strings. In this example, because we are binding a list, it uses ITypedList but doesn't implement ICustomTypeDescriptor.

Note that for PropertyGrid, a simpler shortcut is to use a TypeConverter - this allows you to tweak the properties without having to use ICustomTypeDescriptor or TypeDescriptionProvider - see example.

Marc Gravell
I've done this for lists, didn't know the same approach was valid here, I was experimenting with ICustomTypeDescriptor while waiting for you guys to answer here, but I have another question, I'll accept this answer here for this question and ask another question.
Lasse V. Karlsen
Looking forward to it ;-p
Marc Gravell
Here it is: http://stackoverflow.com/questions/1398109/multiple-bindingsource-components-necessary-for-just-one-data-source, basically it revolves around my flawed/incomplete ICustomTypeDescriptor implementation.
Lasse V. Karlsen