【发布时间】:2015-09-09 14:49:27
【问题描述】:
我有一个包含 ListBox 的 UserControl,我想跟踪该列表框的 SelectedItems。 UserControl 有一个这样定义的 DP“SelectedItemsList”
public static DependencyProperty SelectedItemsListProperty = DependencyProperty.Register(
"SelectedItemsList",
typeof (IList),
typeof (MyListControl),
new FrameworkPropertyMetadata(null,
OnSelectedItemsChanged));
在列表框的项目“SelectionChanged”事件中,我想将选定的项目保存到 DP。每当我更改列表框中的选择时都会触发此操作。
private void OnItemSelectionChanged(object sender, SelectionChangedEventArgs e)
{
SelectedItemsList = this.myListBox.SelectedItems;
}
在包含“MyListControl”的视图中,我创建了一个与要使用所选项目的视图模型的绑定。
<controls:MyListControl
Source="{Binding SomeItemsList, UpdateSourceTrigger=PropertyChanged}"
SelectedItemsList="{Binding SelectedItems, UpdateSourceTrigger=PropertyChanged}"/>
我的问题是,DP SelectedItemsList 永远不会更新。仅当我最初加载列表内容时才会触发 DP 的 PropertyChangeCallback "OnSelectedItemsChanged"。 SelectedItemsList 的值始终为 null。
我知道这个问题类似于Dependency property callback does not work,但那里发布的答案并不能解决我的问题。
我在这里错过了什么?
谢谢,
编辑(2015-09-10): 谢谢大家的cmets。我找到了适合我需要的解决方案:
首先,我创建了一个自定义列表框控件,该控件在依赖属性中提供所选项目的列表(非常类似于Select multiple items from a DataGrid in an MVVM WPF project)。
public class CustomListBox : ListBox
{
public static readonly DependencyProperty SelectedItemsListProperty =
DependencyProperty.Register("SelectedItemsList",
typeof (IList),
typeof (CustomListBox),
new PropertyMetadata(null));
public CustomListBox()
{
SelectionChanged += OnSelectionChanged;
}
public IList SelectedItemsList
{
get { return (IList)GetValue(SelectedItemsListProperty); }
set { SetValue(SelectedItemsListProperty, value); }
}
void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
this.SelectedItemsList= new ArrayList(this.SelectedItems);
}
}
我对“新 ArrayList”部分还不满意,但如果我想在我的视图模型的属性设置器中检查是否相等,则 SelectedItemsList 不能作为 SelectedItems 的引用。以前的值和新的值总是相同的。
然后我将用户控件“MyListControl”的项目选择部分简化为依赖属性本身:
public static DependencyProperty SelectedItemsProperty = DependencyProperty.Register(
"SelectedItems",
typeof (IList),
typeof (MyListControl),
new FrameworkPropertyMetadata(null));
public IList SelectedItems
{
get
{
return (IList)GetValue(SelectedItemsProperty);
}
set
{
SetValue(SelectedItemsProperty, value);
}
}
并修改了MyListControl的xaml:
<controls:CustomListBox
SelectionMode="Extended"
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type controls:MyListControl}},
Path=Source, UpdateSourceTrigger=PropertyChanged}"
SelectedItemsList="{Binding RelativeSource={RelativeSource AncestorType={x:Type controls:MyListControl}},
Path=SelectedItems, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
>
我的 ViewModel 中的属性看起来像
public IList SelectedObjects
{
get { return _selectedObjects; }
set { if (this._selectedObjects != value)
{
this._selectedObjects = value;
OnPropertyChanged(SelectedObjectsProperty);
}
}
}
此属性的类型是 IList 很重要,否则 setter 中的值将始终为 null。
在视图的 xaml 中
<controls:MyListControl
Source="{Binding CurrentImageList, UpdateSourceTrigger=PropertyChanged}"
SelectedItems="{Binding SelectedObjects, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
/>
【问题讨论】:
-
当我添加“SelectedItemsList = null;”在“OnItemSelectionChanged”中的常规集之前,propertychangecallabck 被触发(对于两个集),但与我的 ViewModel 的绑定仍然始终包含“null”。
标签: wpf binding user-controls dependency-properties