Using an abstract type or interface collection as a template dependency property with a UWP template
My model has two classes ItemA
and ItemB
that implement the interface ICustomControlItem
and they are implemented like this ...
public interface ICustomControlItem
{
string Text { get; set; }
}
public class ItemA : ICustomControlItem
{
public string Text { get; set; }
}
public class ItemB : ICustomControlItem
{
public string Text { get; set; }
}
My goal is to create a templated control CustomControl
that has a property (dependency) Items
to be ObservableCollection<ICustomControlItem>
. Used ObservableCollection<T>
as I wanted to update the view when the collection changed.
Accordingly, management is defined as follows:
[ContentProperty(Name = nameof(Items))]
public sealed class CustomControl : Control
{
public CustomControl()
{
DefaultStyleKey = typeof(CustomControl);
Items = new ObservableCollection<ICustomControlItem>();
}
public ObservableCollection<ICustomControlItem> Items
{
get { return (ObservableCollection<ICustomControlItem>)GetValue(ItemsProperty); }
set { SetValue(ItemsProperty, value); }
}
public static readonly DependencyProperty ItemsProperty =
DependencyProperty.Register(nameof(Items), typeof(ObservableCollection<ICustomControlItem>), typeof(CustomControl), new PropertyMetadata(new ObservableCollection<ICustomControlItem>()));
}
... with its XAML ControlTemplate
containing ListView
to render the elements of the dependency property Items
...
<ControlTemplate TargetType="local:CustomControl">
<Grid>
<ListView ItemsSource="{TemplateBinding Items}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Text}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</ControlTemplate>
I used the following XAML to initialize and populate (with class objects ItemA
and ItemB
) an instance CustomControl
in a XAML page.
<local:CustomControl>
<local:ItemA Text="Item #1" />
<local:ItemB Text="Item #2" />
<local:ItemA Text="Item #3" />
</local:CustomControl>
At this point, I expect that everything will be fine, because both ItemA
, and ItemB
implement an interface ICustomControlItem
. However Visual Studio keeps giving me a warning that reads ...
The value of type "ItemA" cannot be added to the collection or dictionary of type "ObservableCollection"
However, despite the errors, the XAML renders correctly in the designer and the app works fine, but IntelliSense does not work in the XAML that VS assumed to be buggy.
I doubt if the issue is related to usage ObservableCollection
because errors don't occur when
-
Items
- thisObservableCollection<object>
(however I need it to bind to the interfaceICustomControlItem
). -
Items
- itemObservableCollection<string>
and<x:String>
are added to the control.
How do I solve this problem and implement a dependency property that is a collection of an abstract type or interface?
source to share