MSDN 上的这篇文章提供了一个很好的示例,说明如何验证此类内容,请查看相应的小节(“验证用户提供的数据”)。关键是使用ValidationRules
并检查对话框的整个逻辑树是否有错误。
编辑: ValidationRule 上的设置应该在这里解决问题。事实上,该属性的 MSDN 文档中的示例正是这种情况。此外,在这种情况下,这个答案可能会引起人们的兴趣。ValidatesOnTargetUpdated
="True"
Edit2:这是我拥有的导致验证失败的完整代码:
<Window x:Class="Test.Dialogs.SearchDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:diag="clr-namespace:Test.Dialogs"
xmlns:m="clr-namespace:HB.Xaml"
Title="Search" SizeToContent="WidthAndHeight" ResizeMode="NoResize"
Name="Window" DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
<Grid.Resources>
<Style x:Key="BaseStyle" TargetType="{x:Type FrameworkElement}">
<Setter Property="Margin" Value="3"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource BaseStyle}"/>
<Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource BaseStyle}"/>
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource BaseStyle}"/>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource BaseStyle}"/>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.Children>
<TextBlock Grid.Column="0" Grid.Row="0" Text="Scope:"/>
<ComboBox Grid.Column="1" Grid.Row="0" ItemsSource="{m:EnumItems {x:Type diag:SearchDialog+ScopeMode}}">
<ComboBox.SelectedItem>
<Binding Path="Scope">
<Binding.ValidationRules>
<diag:HasSelectionValidationRule />
</Binding.ValidationRules>
</Binding>
</ComboBox.SelectedItem>
</ComboBox>
<TextBlock Grid.Column="0" Grid.Row="1" Text="Direction:"/>
<ComboBox Grid.Column="1" Grid.Row="1" ItemsSource="{m:EnumItems {x:Type diag:SearchDialog+DirectionMode}}">
<ComboBox.SelectedItem>
<Binding Path="Direction">
<Binding.ValidationRules>
<diag:HasSelectionValidationRule />
</Binding.ValidationRules>
</Binding>
</ComboBox.SelectedItem>
</ComboBox>
<TextBlock Grid.Column="0" Grid.Row="2" Text="Expression:"/>
<TextBox Name="tb" Grid.Column="1" Grid.Row="2">
<TextBox.Text>
<Binding Path="Expression" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<diag:StringNotEmptyValidationRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<Button Grid.Column="1" Grid.Row="3" Content="Search" Click="Search_Click"/>
</Grid.Children>
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace Test.Dialogs
{
/// <summary>
/// Interaction logic for SearchDialog.xaml
/// </summary>
public partial class SearchDialog : Window
{
public enum ScopeMode { Selection, Document, Solution }
public enum DirectionMode { Up, Down }
public ScopeMode Scope { get; set; }
public DirectionMode Direction { get; set; }
private string _expression = String.Empty;
public string Expression
{
get { return _expression; }
set { _expression = value; }
}
public SearchDialog()
{
InitializeComponent();
}
private void Search_Click(object sender, RoutedEventArgs e)
{
(sender as Button).Focus();
if (IsValid(this)) MessageBox.Show("<Searching>");
else MessageBox.Show("Errors!");
}
bool IsValid(DependencyObject node)
{
if (node != null)
{
bool isValid = Validation.GetHasError(node);
if (!isValid)
{
if (node is IInputElement) Keyboard.Focus((IInputElement)node);
return false;
}
}
foreach (object subnode in LogicalTreeHelper.GetChildren(node))
{
if (subnode is DependencyObject)
{
if (IsValid((DependencyObject)subnode) == false) return false;
}
}
return true;
}
}
public class HasSelectionValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
if (value == null)
{
return new ValidationResult(false, "An item needs to be selected.");
}
else
{
return new ValidationResult(true, null);
}
}
}
public class StringNotEmptyValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
if (String.IsNullOrWhiteSpace(value as string))
{
return new ValidationResult(false, "The search expression is empty.");
}
else
{
return new ValidationResult(true, null);
}
}
}
}