WPF验证器
文章目录
验证行为
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;
namespace ValidationStuday
{
public class ValiationBehavior : Behavior<FrameworkElement>
{
public int _validCount = 0;
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.AddHandler(Validation.ErrorEvent, new EventHandler<ValidationErrorEventArgs>(OnValidationErrors));
}
public void OnValidationErrors(Object sender, ValidationErrorEventArgs e)
{
IValidationExecptionHander validationExecptionHander = null;
if (AssociatedObject.DataContext is IValidationExecptionHander)
{
validationExecptionHander = this.AssociatedObject.DataContext as IValidationExecptionHander;
}
if (validationExecptionHander == null)
return;
var element = e.OriginalSource as UIElement;
if (element == null)
return;
if (e.Action == ValidationErrorEventAction.Added)
{
_validCount++;
}
else if (e.Action == ValidationErrorEventAction.Removed)
{
_validCount--;
}
validationExecptionHander.IsValid = _validCount == 0;
}
protected override void OnDetaching()
{
base.OnDetaching();
this.AssociatedObject.RemoveHandler(Validation.ErrorEvent, new EventHandler<ValidationErrorEventArgs>(OnValidationErrors));
}
}
}
验证结果的接口
用于将验证结果通知出去
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ValidationStuday
{
public interface IValidationExecptionHander
{
bool IsValid { get; set; }
}
}
相应视图的viewModel实现这个接口并重写接口里的属性
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace ValidationStuday
{
public class MainViewModel : IValidationExecptionHander
{
//与视图层的TextBox绑定
private String name;
public String Name
{
get { return name; }
set { name = value; }
}
private bool isValid;
public bool IsValid {
get => isValid;
set => isValid = value;
}
}
}
实现验证规则
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
namespace ValidationStuday
{
public class NoEmptyValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
return String.IsNullOrWhiteSpace((value ?? "").ToString()) ? new ValidationResult(false, "Error") : ValidationResult.ValidResult;
}
}
}
视图层引用验证行为和验证规则
<Window x:Class="ValidationStuday.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ValidationStuday"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<!-- 引用 -->
<i:Interaction.Behaviors>
<local:ValiationBehavior/>
</i:Interaction.Behaviors>
<Grid>
<StackPanel>
<TextBox Width="200" Height="40" VerticalContentAlignment="Center" Margin="20">
<TextBox.Text>
<Binding Path="Name" NotifyOnValidationError="True" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<!-- 引用验证规则 -->
<local:NoEmptyValidationRule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<Button Content="Test" Command="{Binding btnOk}" Width="100" Height="40"/>
</StackPanel>
</Grid>
</Window>
封装RelayCommand命令类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace ValidationStuday
{
public class RelayCommand : ICommand
{
private readonly Action<Object> m_execute;
private readonly Predicate<Object> m_canexecute;
public RelayCommand(Action<Object> m_execute)
{
this.m_execute = m_execute;
}
public RelayCommand(Action<Object> m_execute,Predicate<Object> m_canexecute)
{
this.m_execute = m_execute;
this.m_canexecute = m_canexecute;
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public bool CanExecute(object parameter)
{
if (m_canexecute == null)
{
return true;
}
return m_canexecute(parameter);
}
public void Execute(object parameter)
{
this.m_execute(parameter);
}
}
}
在ViewModel中创建命令并验证TextBox内容的合法性
public RelayCommand btnOk
{
get
{
return new RelayCommand((arg) =>
{
if (!isValid)
{
MessageBox.Show("有毛病", "提示");
}
}, x => true);
}
}