【发布时间】:2019-12-20 02:29:51
【问题描述】:
我将 ComboBox 的 SelectedIndex 属性绑定到 ViewModel 中的一个属性。每次用户从 ComboBox 中选择一个项目时,SelectedItem 区域中都不应出现任何内容(SelectedIndex 应保持为 -1)。为此,我尝试了以下方法:
cs
private int selectedIndexDoor;
public int SelectedIndexDoor
{
get { return selectedIndexDoor; }
set
{
selectedIndexDoor = -1;
OnPropertyChanged("SelectedIndexDoor");
}
}
xaml
<ComboBox Width="150"
materialDesign:HintAssist.Hint="Door"
ItemsSource="{Binding Doors}"
Margin="0, 0, 50, 0"
SelectedIndex="{Binding SelectedIndexDoor,
UpdateSourceTrigger=PropertyChanged}">
</ComboBox>
但是它不起作用。我手动设置索引的值被忽略。这是为什么呢?
【问题讨论】:
-
当绑定更新源属性 (
SelectedIndexDoor) 时,它不会读回值并更新控件。 “接受”的做法是在绑定完成更新后启动另一个更新 vm 属性的线程。如果您希望 viewmodel 属性拒绝来自绑定的更改,请让它抛出异常。 UI 会将其视为验证错误——可能不是您想要的。我认为您可能想要处理 SelectedIndexChanged,并在处理程序中设置SelectedItem=null;或其他东西。您如何使用组合框中的选择? -
您还可以为组合框编写一个 ItemTemplate,该组合框仅在其祖先是 ListBoxItem 时才显示内容。当应用于下拉列表之外的选定项目时,它将不可见。
-
@DavidAndrewThorpe 如果逻辑属于视图,则 .xaml.cs 中的代码是合法的:任何对控件执行操作的代码都属于那里,例如拖放等。我们喜欢放在可能的情况下,这种行为会出现,但并不总是可能或实际的。我在生产代码中使用了 mm8 的解决方案,但我不太喜欢它,因为您正在解决 viewmodel 中的视图问题,它甚至不应该知道视图存在。也就是说,这不是宗教,而是软件开发。
-
@DavidAndrewThorpe 视图模型应该是独立的,并且不知道它的显示方式。也许这个视图模型是通过多个视图显示的,其中一个需要以不同的方式使用 SelectedIndex。
SelectedIndexDoor应该是选择的门索引。确实,您可以有理由相信在这种情况下您最终不会这样做,但这是考虑设计两种不同类型的类的一种非常好的方法:尽可能松散地耦合它们。如果有人出现并为您的视图编写新的视图模型,反之亦然,让他的生活尽可能轻松。 -
感谢@EdPlunkett。我真的很感谢你向我解释:) 是的,我的 xaml.cs 上有一些东西我无法弄清楚如何进入视图模型,例如一些拖放方法,这真的让我很烦!但是好吧,你说在那里有一些代码是合理的,所以我会记住这一点
标签: c# wpf visual-studio combobox