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.

Screenshot

I doubt if the issue is related to usage ObservableCollection

because errors don't occur when

  • Items

    - this ObservableCollection<object>

    (however I need it to bind to the interface ICustomControlItem

    ).
  • Items

    - item ObservableCollection<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?

+3


source to share


1 answer


It looks like the problem was due to a bug in the Visual Studio 2017 Community Edition (or one of its modules) that I installed. Upgrading the IDE (to Version 15.2 (26430.14) Release

) fixed the issue.



0


source







All Articles