C# WPF组合框忽略绑定

C# WPF组合框忽略绑定,c#,wpf,visual-studio,combobox,C#,Wpf,Visual Studio,Combobox,我将组合框的SelectedIndex属性绑定到ViewModel中的属性。每当用户从组合框中选择一个项目时,SelectedItem区域中不应出现任何内容(SelectedIndex应保持为-1)。为此,我尝试了以下方法: cs xaml 但是它不起作用。我手动设置索引的值将被忽略。这是为什么?从源属性的getter返回的值被某些内部逻辑所覆盖,这些逻辑在选择项时执行 您可以通过在另一个调度程序周期中设置值来解决此问题: public int SelectedIndexDoor {

我将组合框的SelectedIndex属性绑定到ViewModel中的属性。每当用户从组合框中选择一个项目时,SelectedItem区域中不应出现任何内容(SelectedIndex应保持为-1)。为此,我尝试了以下方法:

cs

xaml



但是它不起作用。我手动设置索引的值将被忽略。这是为什么?

从源属性的getter返回的值被某些内部逻辑所覆盖,这些逻辑在选择项时执行

您可以通过在另一个调度程序周期中设置值来解决此问题:

public int SelectedIndexDoor
{
    get { return selectedIndexDoor; }
    set
    {
        selectedIndexDoor = value;
        Application.Current.Dispatcher.BeginInvoke(new Action(() =>
        {
            selectedIndexDoor = -1;
            OnPropertyChanged("SelectedIndexDoor");
        }));
    }
}

当绑定更新源属性(
SelectedIndexDoor
)时,它不会读回值并更新控件。“可接受”的方法是在绑定完成更新vm属性后启动另一个线程来更新它。如果希望viewmodel属性拒绝来自绑定的更改,请让它引发异常。UI会将其视为验证错误——可能不是您想要的。我想您可能需要处理SelectedIndexChanged,并将
SelectedItem=null或其他内容。您如何使用组合框中的选择?您还可以为组合框编写一个ItemTemplate,仅当它有一个ListBoxItem的祖先时才显示内容。当应用到下拉列表之外的所选项目时,它将不可见。@DavidAndrewThorpe.xaml.cs中的代码如果属于视图的逻辑,则是合法的:任何对控件进行填充的代码都属于视图,例如,拖放等。我们希望尽可能将此类代码放在行为中,但这并不总是可行或实用的。我在生产代码中使用了mm8的解决方案,但我不太喜欢它,因为您正在解决viewmodel中的视图问题,而viewmodel甚至不应该知道该视图是否存在。也就是说,这不是宗教,而是软件开发。@DavidAndrewThorpe视图模型应该是自包含的,并且不知道它是如何显示的。可能此viewmodel通过多个视图显示,其中一个视图需要以不同方式使用SelectedIndex
SelectedIndexDoor
应为选定的门索引。的确,在这种情况下,您有理由相信最终不会这样做,但考虑设计两种不同类型的类,这是一种非常好的方式:尽可能松散地耦合它们。如果有人来为你的观点写一个新的视图模型,或者反之亦然,让他的生活尽可能地简单。谢谢@EdPlunkett。我真的很感谢你向我解释:)是的,在我的xaml.cs上有一些东西我没有弄清楚如何进入视图模型,比如一些拖放方法,这真的让我很恼火!但好吧,你说上面有一些代码是合理的,所以我会记住这一点
                             <ComboBox Width="150"

                              materialDesign:HintAssist.Hint="Door"
                              ItemsSource="{Binding Doors}"
                              Margin="0, 0, 50, 0"
                              SelectedIndex="{Binding SelectedIndexDoor, 
                             UpdateSourceTrigger=PropertyChanged}">

                            </ComboBox>
public int SelectedIndexDoor
{
    get { return selectedIndexDoor; }
    set
    {
        selectedIndexDoor = value;
        Application.Current.Dispatcher.BeginInvoke(new Action(() =>
        {
            selectedIndexDoor = -1;
            OnPropertyChanged("SelectedIndexDoor");
        }));
    }
}