在SetValue之后从DependencyProperty获取ViewModel中的null &g



我有这个扩展的ListBox与SelectedItems属性,以便能够从SelectionMode设置为extended时获得选定的项目。

public class BindableMultiSelectListBox : ListBox
{
public static new readonly DependencyProperty SelectedItemsProperty =
DependencyProperty.Register("SelectedItems", typeof(IList), typeof(BindableMultiSelectListBox),
new PropertyMetadata(default(IList)));
public new IList SelectedItems
{
get => (IList)GetValue(SelectedItemsProperty);
set => throw new Exception("This property is read-only. To bind to it you must use 'Mode=OneWayToSource'.");
}
protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
base.OnSelectionChanged(e);
SetValue(SelectedItemsProperty, base.SelectedItems);
}
}

我在视图中这样使用:

<usercontrols:BindableMultiSelectListBox SelectedItems="{Binding SelectedDogs, Mode=OneWayToSource}" ItemsSource="{Binding Dogs}" SelectionMode="Extended"/>

并绑定到我的viewModel中的ObservableCollection:

private ObservableCollection<string> _selectedDogs;
public ObservableCollection<string> SelectedDogs
{
get
{
return _selectedDogs;
}
set
{
_selectedDogs = value;
OnPropertyChanged(nameof(SelectedDogs));
}
}

当我调试OnSelectionChanged基础。SelectedItems有预期的选中值,但是当SelectedDogs setter被击中时,值是空的!

我哪里做错了?

目标属性应该绑定到源属性。

初始化视图模型中的源集合:

public ObservableCollection<string> SelectedDogs { get; } = new ObservableCollection<string>();

…并在控件中实现同步:

protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
base.OnSelectionChanged(e);
if (SelectedItems != null)
{
foreach (var removed in e.RemovedItems)
SelectedItems.Remove(removed);
foreach (var added in e.AddedItems)
SelectedItems.Add(added);
}
}

XAML:

... SelectedItems="{Binding SelectedDogs}"

如果要设置source属性,则应在控件中初始化集合。

将viewModel中的SelectedDogs属性从ObservableCollection<string>更改为IList解决了这个问题。

在实践中似乎没有什么不同,但如果我想能够在我的viewModel中指定ObservableCollection呢?为什么ObservableCollection不能工作?它继承自Collection,实现了IList

最新更新