gpt4 book ai didi

c# - 为什么 WPF ComboBox 不能正确反射(reflect)绑定(bind)值?

转载 作者:太空狗 更新时间:2023-10-29 21:29:21 26 4
gpt4 key购买 nike

我有一个 ComboBox,其属性 ItemsSource 和 SelectedValue 绑定(bind)到一个模型。有时,模型需要将所选项目调整为不同的项目,但当我在模型中执行此操作时,模型值未反射(reflect)在 View 中,即使 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>

这是模型:

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. 选择“一”->组合框显示“一”
  3. 选择“二”->组合框显示“二”
  4. 选择“三”->组合框显示“
  5. 选择“四”->ComboBox显示“四”

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

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

最佳答案

当您选择一个项目时,绑定(bind)引擎将更新模型,并将忽略它在调用属性 setter 期间刚刚更改的属性的任何 PropertyChanged。否则,事情可能会进入无限循环。

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

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

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

关于c# - 为什么 WPF ComboBox 不能正确反射(reflect)绑定(bind)值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10079334/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com