【问题标题】:WPF ComboBox MVVM strange behaviorWPF ComboBox MVVM 奇怪的行为
【发布时间】:2011-08-22 16:08:23
【问题描述】:

当我将组合框关联到我的视图模型时,我的行为很奇怪。行为如下,当我更改组合的选定值时,我会验证新值,如果这个新值无效,我会保留旧值并丢弃新值,这样我就不会提高Inotifypropertychanged,但是无论如何都会调用来自与组合框关联的属性的getter,这会获取我想要显示的旧值,但是组合框会显示新值,即使组合的选定值是旧的和正确的值,我在调试模式下检查。我不知道如何解决这个问题,因为我从未见过这种行为,任何建议将不胜感激。

这是 XAML 的代码

<ComboBox Height="23" Name="cbxStatus" HorizontalAlignment="Left"
          ItemsSource="{Binding Path=Status, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
          SelectedItem="{Binding Path=SelectedStatus, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
          DisplayMemberPath="Value" Width="130" VerticalAlignment="Center"
          IsEnabled="{Binding Path=StatusEnable, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> 

这是视图模型代码,属性

public Config SelectedStatus
{
    get
    {
        if (ApplicationAction == ApplicationAction.Add)
        {
            base.Object.State = configManager.BudgetInitStatus();
            StatusEnable = false;
        }
        else
        {
            StatusEnable = true;
        }
        return base.Object.State;
    }
    set
    {
        if (base.Service.CanChangeBudgetStatus(base.Object, value))
        {
            base.Object.State = value;
            base.Object.IsDirty = true;
        }
        RaiseOnPropertyChanged("SelectedStatus");
        RaiseOnPropertyChanged("AssociateOrderButtonVisibility");
    }
}

感谢您的帮助

【问题讨论】:

    标签: wpf data-binding mvvm combobox inotifypropertychanged


    【解决方案1】:

    正如我在对 Jay 的评论中所指出的,这里的问题是 WPF 正在设置值,而不是听您的更改通知(毕竟,这是预期的)。您需要做的是在当前消息的上下文之外引发属性更改通知。您可以使用调度程序执行此操作,例如:

    set
    {
        if (!valid)
        {
            // value is unchanged
            Dispatcher.BeginInvoke(delegate { this.OnPropertyChanged(...) });
            return;
        }
    
        // value is changed here
    }
    

    这将确保当前数据绑定消息被执行,然后一个单独的消息告诉 WPF,“实际上,你刚刚提供给我的 setter 的值不再是当前值”。

    如果您愿意,也可以使用SynchronizationContext。无论哪种方式,我承认这有点hacky。不幸的是,我不知道解决这个问题的好方法。事实上,WPF 假定它传递给您的 setter 的值是属性的有效值。绑定操作上下文中的任何属性更改通知都无法说服它。

    【讨论】:

    • Kent,您认为使用Async=True 来完成此操作的潜在缺点是什么?
    【解决方案2】:

    将绑定设置为

    IsAsync=True
    

    会起作用的。

    【讨论】:

    • 您好,感谢您的回答,我尝试了两种可能性,也将两者结合起来,但在我的情况下,这是一个有效的方法,虽然我认为两者都有点 hacky,我不明白为什么这一项工作,因为从我在 msdn 中阅读的内容来看,这只是为了在绑定过程的后期获取一个属性,可以这么说。我认为组合框应该足够“智能”,可以看到当 selecteditem 属性被“通知”时应该显示该值而不是先前选择的值......但这是我的观点。再次感谢您的帮助
    【解决方案3】:

    当用户更改组合框中的值时,组合框中的值也会发生变化,而与您的视图模型无关。

    如果您改回该值并且不发出属性更改通知,您的视图模型和视图将不同步。

    简而言之,当你拒绝选择的值时,你仍然需要属性更改通知。

    【讨论】:

    • 即使有更改通知(他有),WPF 也会忽略更改,因为它期望在那个时间点收到更改通知。它不期望的是该值不是它提供给属性设置器的值。
    猜你喜欢
    • 1970-01-01
    • 2012-06-19
    • 2013-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-20
    相关资源
    最近更新 更多