Reputation: 483
As the SelectedItems property
of the ListBox control is a normal property and not a dependency property to bind to, I have derived of the ListBox and created a new dependency property SelectedItemsEx
.
But my XAML compiler keeps giving me the error
A 'Binding' cannot be set on the 'SelectedItemsEx' property of the type 'MyListBox'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.
Why my property is not recognized as a dependency property? Any help is appreciated, thank you!
XAML:
<MyListBox ItemsSource="{Binding MyData}" SelectedItemsEx="{Binding SelectedEx}"
SelectionMode="Extended"> ... </MyListBox>
ListBox' implementation:
public class MyListBox : ListBox
{
public readonly DependencyProperty SelectedItemsExProperty =
DependencyProperty.Register("SelectedItemsEx",
typeof(ObservableCollection<MyItemsDataType>),
typeof(MyListBox),
new PropertyMetadata(default(ObservableCollection<MyItemsDataType>)));
public ObservableCollection<MyItemsDataType> SelectedItemsEx
{
get
{
var v = GetValue(SelectedItemsExProperty);
return (ObservableCollection<MyItemsDataType>)v;
}
set { SetValue(SelectedItemsExProperty, value); }
}
protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
base.OnSelectionChanged(e);
if (SelectedItemsEx != null)
{
SelectedItemsEx.Clear();
foreach (var item in base.SelectedItems)
{
SelectedItemsEx.Add((MyItemsDataType)item);
}
}
}
Upvotes: 0
Views: 920
Reputation: 128136
The DependencyProperty
field must be static:
public static readonly DependencyProperty SelectedItemsExProperty = ...
Note also that in order to make your derived ListBox a little more reusable, you should not constrain the type of the SelectedItemsEx
property. Use IEnumerable
(or IList
like SelectedItems
) instead. Moreover, there is no need to specify a default value by property metadata, as it is null
already and default(<any reference type>)
is also null
.
You will however have to get notified whenever the SelectedItemsEx
property has changed. Therefore you have to register a change callback via property metadata:
public static readonly DependencyProperty SelectedItemsExProperty =
DependencyProperty.Register(
"SelectedItemsEx", typeof(IEnumerable), typeof(MyListBox),
new PropertyMetadata(SelectedItemsExPropertyChanged));
public IEnumerable SelectedItemsEx
{
get { return (IEnumerable)GetValue(SelectedItemsExProperty); }
set { SetValue(SelectedItemsExProperty, value); }
}
private static void SelectedItemsExPropertyChanged(
DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var listBox = (MyListBox)obj;
var oldColl = e.OldValue as INotifyCollectionChanged;
var newColl = e.NewValue as INotifyCollectionChanged;
if (oldColl != null)
{
oldColl.CollectionChanged -= listBox.SelectedItemsExCollectionChanged;
}
if (newColl != null)
{
newColl.CollectionChanged += listBox.SelectedItemsExCollectionChanged;
}
}
private void SelectedItemsExCollectionChanged(
object sender, NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
{
...
}
}
Upvotes: 3