The title is a bit blur here, I didn’t find a way to say it more clearly.
Let’s take a simple and very clear example of my situation:
First: I have a custom control, FooControl , with a DependencyProperty of type IFoo. The control is supposed to display IFoo objects in a DataGrid
Please note that, of course, the real object is not just about displaying some values, I could have used just a DataGrid for this matter 😉
public class FooControl : DataGrid
{
/// <summary>
/// Foo!
/// </summary>
public static readonly DependencyProperty FooProperty =
DependencyProperty.Register("Foo",
typeof(IFoo),
typeof(FooControl),
new PropertyMetadata(FooChanged));
Second: I have an IFoo interface
public interface IFoo
{
IList<double> Values { get; set; }
}
Third: I have a Foo object, implementing IFoo
public class Foo : IFoo
{
public IList<double> Values { get; set; }
}
And now, I want an ObservableFoo, for binding updates purpose, here it is:
public class ObservableFoo : Foo, INotifyCollectionChanged
{
public ObservableCollection<double> ObservableValues {get; set; }
}
Now, THE PROBLEM:
I usually have my FooControls bound to objects of type Foo, which are “strict” implementations of the IFoo interface.
Now, I also need to have three FooControls which should be bound to objects of type ObservableFoo (which obviously are IFoo, but also add a property not specified in the interface, ie ObservableValues )
in the FooControl class, I manually set a binding to the values to be displayed:
/// <summary>
/// Sets the binding on foo values
/// </summary>
/// <param name="propertyPath">Binding path</param>
public void SetValuesBinding(string propertyPath)
{
// Binding for foovalues
Binding fooBinding = new Binding(propertyPath);
fooBinding.Converter = new FooConverter();
fooBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
fooBinding.RelativeSource = new RelativeSource(RelativeSourceMode.Self);
fooBinding.Mode = BindingMode.TwoWay;
this.SetBinding(FooControl.ItemsSourceProperty, fooBinding);
}
When propertyPath is Foo.Values , it works fine, updating the binding’s target will call the PropertyChangedHandler I defined for ItemsSource
When propertyPath is Foo.ObservableValues, updating the binding won’t call the PropertyChangedHandler I defined. However, there is no Binding error displayed on the output window!
In my comprehension of the problem, it means that:
- The Binding “worked”, ie. it has found the source property
- BUT, since
ObservableValuesis not inIFoobut only inObservableFoo, the binding tries to findIFoo.ObservableValuesand… cannot update it.
How could I manage to update the binding to ObservableValues ?
I hope I made it clear enough for you guys. Please feel free to ask any question if you need me to clarify
Okay, I finally went for a workaround.
I Added a property to the
FooControl:And I bind the embedded Datagrid’s
ItemSourceto this property (using aRelativeSourcepointing to itself) and… It works fine.But still, this made me learn something: binding does not resolve types at runtime, it will just take the specified type apparently!