更改setter中的SelectedItem值对组合框没有影响
本文关键字:组合 有影响 setter 中的 SelectedItem 更改 | 更新日期: 2023-09-27 18:26:46
我有一个ComboBox
,它的SelectedItem
和ItemsSource
是绑定到视图模型的数据。无论何时选择"Blue"
,setter都会设置值"Green"
并触发PropertyChanged
事件。
在这种情况下,我希望ComboBox
显示"Green"
,而显示的值保持为"Blue"
。
我已经对CheckBox
进行了同样的尝试(绑定到IsChecked
,无论何时将值设置为true
并激发PropertyChanged
,都会将其还原为false
),并且它在那里可以正常工作。
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)));
}
}
这确实有点奇怪。事实证明,尽管组合框显示"蓝色",但它的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
属性集。
您可以使用LostFocus作为UpdateSourceTrigger
<ComboBox
VerticalAlignment="Top"
x:Name="ComboBox"
SelectedItem="{Binding SelectedItem, UpdateSourceTrigger=LostFocus}"
ItemsSource="{Binding Values}" />