我想要完成的是能够验证输入到可编辑组合框中的新类别或从现有组合框的类别列表中选择一个。
验证仅适用于 selectedItem,不适用于输入到 Text 中的新文本。一旦我添加ValidateOnDataErrors="True"
到 ComboBox'es Text 属性,输入新文本的事件就不会触发。Category 是一个带有 Id 和 Name 的简单对象。
XAML:
<Window.Resources>
<ControlTemplate x:Key="ValidationErrorTamplate">
<Border BorderBrush="DodgerBlue" BorderThickness="0.75">
<AdornedElementPlaceholder />
</Border>
</ControlTemplate>
<Style x:Key="ElementInError" TargetType="{x:Type FrameworkElement}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="ToolTip" Value="{Binding (Validation.Errors)[0].ErrorContent, RelativeSource={x:Static RelativeSource.Self}}" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<ComboBox Name="CbCategory"
DisplayMemberPath="Name"
IsEditable="True"
ItemsSource="{Binding Categories}"
SelectedItem="{Binding SelectedCategory,
UpdateSourceTrigger=PropertyChanged,
ValidatesOnDataErrors=True}"
Style="{StaticResource ElementInError}"
Text="{Binding NewCategory.Name,
UpdateSourceTrigger=PropertyChanged,
ValidatesOnDataErrors=True}"
Validation.ErrorTemplate="{StaticResource ValidationErrorTamplate}" />
视图模型:( : IDataErrorInfo
)
private Category _newCategory;
private Category _selectedCategory;
public ExpenseCategory SelectedCategory
{
get { return _selectedCategory; }
set
{
if (Equals(_selectedCategory, value)) return;
_selectedCategory = value;
SendPropertyChanged("SelectedCategory");
}
}
public ExpenseCategory NewExpenseCategory
{
get { return _newExpenseCategory ?? (_newExpenseCategory = new ExpenseCategory()); }
set
{
if (Equals(_newExpenseCategory, value)) return;
_newExpenseCategory = value;
SendPropertyChanged("NewExpenseCategory");
}
}
public string this[string propertyName]
{
get
{
switch (propertyName)
{
case "SelectedExpenseCategory":
case "NewExpenseCategory":
{
if ((SelectedCategory == null) || (NewCategory == null)
{
return "Category must be selected or entered";
}
}
break;
}
return string.Empty;
}