开发者

How should I expose a collection on a UserControl?

I'm creating a UserControl which will be used in various scenarios. I need to expose a collection of strings from the UserControl and I'm not sure how to do it.

The two possible uses I see are:

  • a control on its containing control binds to the collection, e.g. a ListBox;
  • a property on the containing control's ViewModel needs to bind to the collection.

I can get the former to work with a public ObservableCollection<String> property on the UserControl but it won't work for the latter. (I get "Object of type 'System.Windows.Data.Binding' cannot be converted to type 'System.Collections.ObjectModel.Observa开发者_C百科bleCollection`1[System.String]'.")

Is there a solution that will work for both?

EDIT

This is my stab at a UML diagram showing what I'm doing:

How should I expose a collection on a UserControl?


I think the problem is just that the binder can't understand generics. You should be able to get around that by inheriting from ObservableCollection<string> to make a non-generic class. You can use something like this:

class StringCollection : ObservableCollection<string> { }

Since you are using that property as a target of a binding, you must declare it as a DependencyProperty:

class ObjectSelectorView
{
    public StringCollection ObjectNames
    {
        get { return (StringCollection)GetValue(ObjectNamesProperty); }
        set { SetValue(ObjectNamesProperty, value); }
    }

    // Using a DependencyProperty as the backing store for ObjectNames.
    // This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ObjectNamesProperty = 
        DependencyProperty.Register("ObjectNames", typeof(StringCollection),
            typeof(ObjectSelectorView), null);
   ....
}


I would suggest that the error you are seeing is actually the result of your not implementing this property as dependency property. You should be using a dependency property here.

Don't expose the property on your control as a concrete ObservableCollection of anything. Instead expose the property as a simple non-generic IList.

In your control's constructor assign an initial empty instance of ObservableCollection<String> to this property. However the property should have a public setter and therefore your initial collection instance may be replaced by some other implementer of IList. Therefore you should limit your usage of this property internally to IList or gracefully degrade behaviour if the current instance does not have the other interfaces you might want.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜