繁体   English   中英

为什么 WPF ComboBox 不能正确反映绑定值?

[英]Why doesn't WPF ComboBox reflect properly the bound value?

我有一个 ComboBox,其属性 ItemsSource 和 SelectedValue 绑定到 model。有时,model 需要将所选项目调整为不同的项目,但是当我在 model 中执行此操作时,model 值未反映在视图中,即使正确设置了 SelectedValue(使用 snoop 和 SelectionChanged 事件处理程序进行了检查)。

为了说明问题,这里有一个简单的 xaml:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Grid>
      <ComboBox Height="25" Width="120" SelectedValue="{Binding SelectedValue}" SelectedValuePath="Key" ItemsSource="{Binding PossibleValues}" DisplayMemberPath="Value"/>
   </Grid>
</Window>

这是 model:

using System.Collections.Generic;
using System.Windows;
using System.ComponentModel;

namespace WpfApplication1
{
   public partial class MainWindow : Window, INotifyPropertyChanged
   {
      int m_selectedValue = 2;
      Dictionary<int, string> m_possibleValues = new Dictionary<int, string>() { { 1, "one" }, { 2, "two" }, { 3, "three" }, {4,"four"} };

      public int SelectedValue
      {
         get { return m_selectedValue; }
         set 
         {
            if (value == 3)
            {
               m_selectedValue = 1;
            }
            else
            {
               m_selectedValue = value;
            }
            PropertyChanged(this, new PropertyChangedEventArgs("SelectedValue"));
         }
      }
      public Dictionary<int, string> PossibleValues
      {
         get { return m_possibleValues; }
         set { m_possibleValues = value; }
      }


      public MainWindow()
      {
         InitializeComponent();
      }

      public event PropertyChangedEventHandler PropertyChanged;
   }
}

我预计行为如下:

  1. 最初,选择了两个
  2. Select “一” -> ComboBox 显示“一”
  3. Select“二”-> ComboBox显示“二”
  4. Select “三” -> ComboBox 显示“
  5. Select“四”-> ComboBox显示“四”

但是,在#4 中,显示“三”。 为什么? model 中的值已更改为 1(“一”),但 View 仍显示 3(“三”)。

我通过显式更新 SelectionChanged 事件处理程序中的绑定目标找到了解决方法,但这似乎是错误的。 还有另一种方法可以实现这一目标吗?

当您 select 一个项目时,绑定引擎将更新 model,并将忽略它在调用属性设置器期间刚刚更改的属性的任何PropertyChanged 如果没有,事情可能 go 进入无限循环。

系统假定设置器不会更改传递给它的值。 这里的解决方法很简单:使用Dispatcher.BeginInvoke()或在您的绑定上设置IsAsync=True以获得您正在寻找的行为。 但是,我个人强烈反对您这样做。 不仅因为它引入了一大堆与计时相关的新问题,而且主要是因为它是解决本来不应该存在的问题的解决方法。

不要这样做。 它不仅适用于 WPF:任何改变 setter 的东西都可以期望它刚刚设置的值被正确设置,不会抛出异常。 更改 setter 内部的值是违反直觉的,以后可能会咬你。 此外,如果您的应用程序用户看到 combobox 忽略了它的选择,这真的会令人不安。

如果您不喜欢传递的值,请抛出异常并使用Binding.ValidatesOnExceptions告诉 WPF 它是预期的。 如果您不希望用户使用 select 这个值,请不要首先将其放入列表中。 如果该项目由于其他业务规则不应有条件地可用,请动态过滤列表或应用触发器。

在绑定到ComboBox控件的SelectedValue和/或SelectedItem属性时,我在正确更新控件方面一直存在问题。

为了解决这个问题,我不得不改为绑定到SelectedIndex属性。 在我的 ViewModel 中处理“索引”属性比较麻烦,但它解决了ComboBox未更新的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM