namespace WpfApp4.DataValidate { public class RangeValidationRule : ValidationRule { public override ValidationResult Validate(object value, CultureInfo cultureInfo) { double d = 0; if(double.TryParse(value.ToString(),out d)) { if(d>=0 && d <= 100) { return new ValidationResult(true,null); } } return new ValidationResult(false, "数据必须在0~100之间"); } } }2. 设置规则
<TextBlock Text="年龄" VerticalAlignment="Center"></TextBlock> <TextBox x:Name="tbAge" Width="120" Height="25" Margin="10" Validation.Error="tbAge_Error" VerticalContentAlignment="Center"> <TextBox.Text> <Binding Path="Age" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True"> <Binding.ValidationRules> <v:RangeValidationRule ValidatesOnTargetUpdated="True"></v:RangeValidationRule> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> <TextBlock VerticalAlignment="Center" Text="{Binding DataError}" Foreground="Red"></TextBlock>关于校验规则,有以下几点需要注意:
private void tbAge_Error(object sender, ValidationErrorEventArgs e) { this.viewModel.ValidationErrorCommand.Execute(e); }其中上述方法中的命令为ViewModel中定义,如下所示:
public class MainWindowViewModel : ObservableObject { private int age; public int Age { get { return age; } set { SetProperty(ref age , value); } } private string dataError; public string DataError { get { return dataError; } set { SetProperty(ref dataError , value); } } private TextBox textBox; private ICommand winLoadedCommand; public ICommand WinLoadedCommand { get { if (winLoadedCommand == null) { winLoadedCommand = new RelayCommand<object>(WinLoaded); } return winLoadedCommand; } } private void WinLoaded(object sender) { if (sender != null) { var win = sender as MainWindow; this.textBox = win.tbAge; } } private ICommand validationErrorCommand; public ICommand ValidationErrorCommand { get { if (validationErrorCommand == null) { validationErrorCommand = new RelayCommand<object>(DisplayValidationError); } return validationErrorCommand; } } private void DisplayValidationError(object obj) { if (Validation.GetErrors(this.textBox).Count > 0) { this.DataError= Validation.GetErrors(this.textBox)[0].ErrorContent.ToString(); } else { this.DataError = string.Empty; } } }4. 数据校验示例演示
namespace WpfApp4.DataConverter { public class BoolToVisilityConverter : IValueConverter { /// <summary> /// Source 到 Target /// </summary> /// <param name="value"></param> /// <param name="targetType"></param> /// <param name="parameter"></param> /// <param name="culture"></param> /// <returns></returns> public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var flag = bool.Parse(value.ToString()); if(flag) { return Visibility.Visible; } else { return Visibility.Collapsed; } } /// <summary> /// Target到Source /// </summary> /// <param name="value"></param> /// <param name="targetType"></param> /// <param name="parameter"></param> /// <param name="culture"></param> /// <returns></returns> public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { var visibility = Visibility.Collapsed; if (Enum.TryParse<Visibility>(value.ToString(), out visibility)) { if (visibility == Visibility.Collapsed) { return false; } else if(visibility == Visibility.Visible) { return true; } else { return false; } } return false; } } }注意:IValueConverter接口共两个方法,其中Convert方法当Source到Target时调用,ConvertBack方法则是反方向调用。
<Window.Resources> <c:BoolToVisilityConverter x:Key="boolToVisility"></c:BoolToVisilityConverter> </Window.Resources>3. 调用类型转换
<StackPanel Orientation="Horizontal" Grid.Row="0"> <CheckBox Content="显示" x:Name="chk01"></CheckBox> </StackPanel> <StackPanel Orientation="Horizontal" Grid.Row="1" Visibility="{Binding ElementName=chk01, Path=IsChecked, Converter={StaticResource boolToVisility}}"> <TextBlock Text="年龄" VerticalAlignment="Center"></TextBlock> <TextBox x:Name="tbAge" Width="120" Height="25" Margin="10" Validation.Error="tbAge_Error" VerticalContentAlignment="Center"> <TextBox.Text> <Binding Path="Age" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True"> <Binding.ValidationRules> <v:RangeValidationRule ValidatesOnTargetUpdated="True"></v:RangeValidationRule> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> <TextBlock VerticalAlignment="Center" Text="{Binding DataError}" Foreground="Red"></TextBlock> </StackPanel>
示例演示