WPF ComboBox MVVM奇怪的行为

时间:2011-05-10 17:22:40

标签: wpf data-binding mvvm combobox inotifypropertychanged

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

这是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}"/> 

这是viewmodel代码,属性

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");
    }
}

感谢您的帮助

3 个答案:

答案 0 :(得分:4)

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

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

    // value is changed here
}

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

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

答案 1 :(得分:2)

将绑定设置为

IsAsync=True

会奏效。

答案 2 :(得分:0)

当用户更改组合框中的值时,无论您的视图模型如何,它都会在组合框中更改。

如果您更改该值并且未提出属性更改通知,则您的viewmodel和视图将不同步。

简而言之,当您拒绝所选值时,您仍需要更改属性通知。