I have some types hierarchy:
public class Base {}
public class Derived_1 : Base {}
public class Derived_2 : Base {}
// more descendants...
public class Derived_N : Base {}
Types from this hierarchy are used as lookup lists in view models:
public class SomeViewModel
{
// available items
public IEnumerable<Derived_N> SomeItems { get; }
// currently selected item
public Derived_N SelectedItem { get; set; }
// there could be several property pairs as above
}
To select values from lookup list I've created user control (some sort of selector). Since from the point of selection process all Base descendants looks similar, user control operates Base type properties:
public IEnumerable<Base> ItemsSource
{
get { return (IEnumerable<Base>)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register("ItemsSource", typeof(IEnumerable<Base>), typeof(BaseSelector), new PropertyMetadata(null));
public Base SelectedItem
{
get { return (Base)GetValue(SelectedItemProperty); }
set { SetValue(SelectedItemProperty, value); }
}
public static readonly DependencyProperty SelectedItemProperty =
DependencyProperty.Register("SelectedItem", typeof(Base), typeof(BaseSelector), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
XAML usually looks like:
<myCtrls:BaseSelector ItemsSource="{Binding SomeItems}"
SelectedItem="{Binding SelectedItem}"/>
This works as expected, but there are binding errors like this:
Cannot create default converter to perform 'two-way' conversions between types 'Derived_N' and 'Base'
I know, why they are in output window - in theory, SelectedItem could be any type, derived from Base, but in practice this is not my case.
The error disappears, if this converter:
public class DummyConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
}
is used in binding:
<myCtrls:BaseSelector ItemsSource="{Binding SomeItems}"
SelectedItem="{Binding SelectedItem, Converter={StaticResource DummyConverterKey}}"/>
but I don't want to use it at all - as you can see, there are no any payload in that converter (while there are lot such of properties).
Are there any other workaround?
For now, I've solved a problem with replacing property type for user control's properties to IEnumerable / object respectively (IEnumerable<object> / object is also a solution):
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(BaseSelector), new PropertyMetadata(null));
public static readonly DependencyProperty SelectedItemProperty =
DependencyProperty.Register("SelectedItem", typeof(object), typeof(BaseSelector), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
This leads to extra type checking inside user control, but doesn't generate any binding errors (and I really don't understand, why - the case with object is the same as with Base, IMO).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With