我正在尝试在绑定到 itemssource 和 selecteditem 的组合框中调试一个奇怪的错误。这让我疯狂。
更改存在组合框的选定 tabitem 时会出现问题。(实际上只是在更改 ComboBox 的 DataContext 时)。SelectedItem 绑定有一个自定义验证规则,如果值为 null,则会给出错误。
问题是 wpf 在切换tabitems (DataContext) 时调用我的自定义规则并尝试验证 null 值,即使 selecteditem-source 永远不会为 null。这是个问题。
这是我制作的一个简化案例,显示了相同的错误:
在NotNullValidationRule.Validate中设置断点并查看 WPF 如何尝试将 SelectedItem 验证为 null,即使它不存在于任何视图模型实例中。
更新
经过更多的实验,我发现 TabControl 实际上是无关紧要的。即使使用一个简单的 ComboBox 和一个按钮来切换它的 DataContext,我也会遇到完全相同的问题。我正在用新版本替换代码示例。
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
namespace ComboBoxValidationBugTest
{
public partial class MainWindow : Window
{
private Test t1, t2;
public MainWindow()
{
InitializeComponent();
t1 = new Test();
t1.Items.Add("A");
t1.Items.Add("B");
t1.Items.Add("C");
t1.SelectedItem = "A";
t2 = new Test();
t2.Items.Add("B");
t2.Items.Add("C");
t2.Items.Add("D");
t2.SelectedItem = "B";
ComboBox1.DataContext = t1;
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
ComboBox1.DataContext = ComboBox1.DataContext == t1 ? t2 : t1;
}
}
public class Test : INotifyPropertyChanged
{
private string _selectedItem;
private ObservableCollection<string> _items = new ObservableCollection<string>();
public ObservableCollection<string> Items
{
get
{
return _items;
}
}
public string SelectedItem
{
get
{
return _selectedItem;
}
set
{
_selectedItem = value;
OnPropertyChanged("SelectedItem");
}
}
public override string ToString()
{
return _selectedItem;
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class NotNullValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
if (value == null)
{
return new ValidationResult(false, "Value was null");
}
return new ValidationResult(true, null);
}
}
}
和 XAML:
<Window x:Class="ComboBoxValidationBugTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:comboBoxValidationBugTest="clr-namespace:ComboBoxValidationBugTest"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DockPanel>
<Button Content="Toggle DataContext" DockPanel.Dock="Top" Click="ButtonBase_OnClick" />
<ComboBox ItemsSource="{Binding Items}" VerticalAlignment="Top" x:Name="ComboBox1">
<ComboBox.SelectedItem>
<Binding Path="SelectedItem">
<Binding.ValidationRules>
<comboBoxValidationBugTest:NotNullValidationRule />
</Binding.ValidationRules>
</Binding>
</ComboBox.SelectedItem>
</ComboBox>
</DockPanel>
</Grid>
</Window>