【问题标题】:Changing SelectedItem value in setter has no effect on ComboBox在 setter 中更改 SelectedItem 值对 ComboBox 没有影响
【发布时间】:2015-12-15 10:10:34
【问题描述】:

我有一个ComboBox,其SelectedItemItemsSource 是数据绑定到视图模型的。无论何时选择"Blue",SETTER反而设置了值"Green"并触发PropertyChanged事件。

我希望ComboBox 在这种情况下显示"Green",而不是显示的值仍然是"Blue"

我用CheckBox(绑定到IsChecked,将值恢复为false,只要它设置为true并触发PropertyChanged),它就可以正常工作了。

MainWindow.xaml:

<Window x:Class="WpfTestApplication.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="80" Width="100">
    <Grid>
        <ComboBox x:Name="ComboBox" SelectedItem="{Binding SelectedItem}" ItemsSource="{Binding Values}" />
    </Grid>
</Window>

MainWindow.xaml.cs:

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

namespace WpfTestApplication
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            ComboBox.DataContext = new ViewModel();
        }
    }

    public class ViewModel : INotifyPropertyChanged
    {
        public List<string> Values { get; set; } = new List<string>
        {
            "Green", "Red", "Blue"
        };

        public string SelectedItem
        {
            get { return selectedItem; }
            set
            {
                selectedItem = value;

                if (selectedItem == "Blue")
                    selectedItem = "Green";

                SelectedItemChanged();
            }
        }

        private string selectedItem = "Red";

        public event PropertyChangedEventHandler PropertyChanged;

        public void SelectedItemChanged() =>
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedItem)));
    }
}

【问题讨论】:

  • 检查 Combobox IsSynchronizedWithCurrentItem 属性是否设置为“True”。
  • 呃。多年后,这个仍然是一个令人头疼的问题:) 两个答案都有效,但有延迟的那个看起来更糟,因为人们可以看到延迟开始了。

标签: c# wpf xaml data-binding combobox


【解决方案1】:

确实有点奇怪。事实证明,即使组合框显示“蓝色”,它的SelectedItem 现在声称是预期的“绿色”。我不知道为什么显示的值和以编程方式可访问的 SelectedItem 值之间存在差异,但我确实找到了解决方法:

<ComboBox
    VerticalAlignment="Top"
    x:Name="ComboBox"
    SelectedItem="{Binding SelectedItem, Delay=1}"
    ItemsSource="{Binding Values}" />

Delay 可以解决问题,所以这里肯定存在一些时间问题。

我试图创建一个适当的依赖属性,希望值强制可以解决问题:

public sealed partial class MainWindow
{
    private static readonly DependencyProperty SelectedItemProperty =
        DependencyProperty.Register(
            "SelectedItem",
            typeof(string),
            typeof(MainWindow),
            new PropertyMetadata("Red", SelectedItemChanged, SelectedItemCoerceValue));

    private static void SelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
    }

    private static object SelectedItemCoerceValue(DependencyObject d, object basevalue)
    {
        if ("Blue".Equals(basevalue))
        {
            return "Green";
        }

        return basevalue;
    }

    public List<string> Values { get; set; } = new List<string>
        {
            "Green", "Red", "Blue",
        };

    public MainWindow()
    {
        InitializeComponent();
        ComboBox.DataContext = this;
    }
}

不幸的是,它还需要Delay 属性集。

【讨论】:

    【解决方案2】:

    您可以将 LostFocus 用作 UpdateSourceTrigger

    <ComboBox
        VerticalAlignment="Top"
        x:Name="ComboBox"
        SelectedItem="{Binding SelectedItem, UpdateSourceTrigger=LostFocus}"
        ItemsSource="{Binding Values}" />
    

    【讨论】:

    • 嗯,这似乎也是一种解决方法(就像接受的答案一样)。
    猜你喜欢
    • 2012-01-18
    • 1970-01-01
    • 2011-02-04
    • 2016-06-15
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    • 1970-01-01
    • 2014-08-13
    相关资源
    最近更新 更多