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:
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.
精彩评论