在setter中更改SelectedItem值对ComboBox没有影响

时间:2015-12-15 10:10:35

标签: c# wpf xaml data-binding combobox

我有一个ComboBox,其SelectedItemItemsSource与视图模型绑定数据。只要选择"Blue",设置者就会设置值"Green"并触发PropertyChanged事件。

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

我使用CheckBox尝试了同样的操作(绑定到IsChecked,只要将false设置为true,就将值恢复为PropertyChangedMainWindow.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))); } }

{{1}}

2 个答案:

答案 0 :(得分:3)

这确实有点奇怪。事实证明,即使组合框显示“蓝色”,它的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属性集。

答案 1 :(得分:0)

您可以将LostFocus用作UpdateSourceTrigger

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