【发布时间】:2013-12-10 10:35:27
【问题描述】:
背景
我有一个包含ParentViewModel 项目的列表框:
<listBox x:Name="lstParentItems"
ItemsSource="{Binding ParentItems}"
SelectedItem={Binding SelectedParent, Mode=OneWayToSource}">
</ListBox>
每个父实例都有一个子项列表:ObservableCollection<ChildViewModel> ChildItems。当我选择一个父项时,我会在另一个列表框中显示子项列表:
<!-- displays a list of ChildViewModels for currently selected ParentViewModel -->
<ListBox x:Name="lstChildItems" DataContext={Binding SelectedParent}"
ItemsSource="{Binding ChildItems}"
SelectedItem="{Binding SelectedChild, Mode=OneWayToSource}"
SelectionChanged="lstChildItems_SelectionChanged"
MouseDoubleClick="lstChildItems_MouseDoubleClick">
</ListBox>
如您所见,我希望 Parent 实例知道当前选择了哪个 Child。
问题
在调试一个不同的错误时,我发现了一个奇怪的行为,某种 setter 循环。我在 SelectedChild 设置器中设置了一个调试断点,如下所示:
public ChildViewModel SelectedChild {
get { return _selectedChild; }
set {
_selectedChild = value;
RaisePropertyChanged("SelectedChild");
}
}
当我选择一个子项时,setter 不会调用一次,而是一遍又一遍地执行。 调试器在断点处(RaisePropertyChanged 行)一直暂停,单击 Continue 后立即暂停又在同一个地方。
我不知道这种行为是从哪里来的。任何想法从哪里开始寻找? 我很乐意提供任何所需的详细信息。到目前为止,我应该提一下:
-
SelectedChild属性不参与任何其他绑定(XAML 或代码) -
SelectedChild从未在代码中分配给 - 在
ChildViewModel我有一个CanCommandExecute 方法来检查SelectedChild != null -
lstChildItems中的代码隐藏事件处理程序用于与难以直接合并到我的 MVVM 架构中的 COM 控件进行交互;他们所做的只是阅读有关SelectedChild的一些信息(如果它不为空);没有分配
【问题讨论】:
-
您如何在父项更改时填写 ChildItems?
-
lstParentsListBox 中显示的每个父级都已经在内存中拥有一个子级列表。选定的父项更改不会发生“填充”。 -
你不应该从你的设置器中调用
RaisePropertyChanged,除非值实际上改变了,顺便说一句。
标签: .net wpf data-binding infinite-loop