wpf内容控制验证
如何对ContentControl进行验证? 有一个类负责存储具有度量单位的值,它通过数据集显示在内容控件中,我想在显示和编辑它时检查其正确性,例如,单位不能有值2,或者该值应该小于10000。使用多重绑定解决此问题,编辑值时不满足验证规则 Xaml文件:wpf内容控制验证,wpf,validation,contentcontrol,Wpf,Validation,Contentcontrol,如何对ContentControl进行验证? 有一个类负责存储具有度量单位的值,它通过数据集显示在内容控件中,我想在显示和编辑它时检查其正确性,例如,单位不能有值2,或者该值应该小于10000。使用多重绑定解决此问题,编辑值时不满足验证规则 Xaml文件: <Window x:Class="DELETE1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
<Window x:Class="DELETE1.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:DELETE1"
xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
mc:Ignorable="d"
x:Name="m_win"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<DataTemplate DataType="{x:Type local:ValWithUnits}">
<Border>
<DockPanel>
<ComboBox DockPanel.Dock="Right" Width="60" IsEnabled="True" SelectedIndex="{Binding Unit}" ItemsSource="{Binding Src, ElementName=m_win}" />
<TextBox Text="{Binding Val, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEnabled="True"/>
</DockPanel>
</Border>
</DataTemplate>
<local:MultiBindingConverter x:Key="MultiBindingConverter" />
</Window.Resources>
<Grid>
<ContentControl x:Name="m_contentControl">
<ContentControl.Content>
<MultiBinding Mode="TwoWay" NotifyOnValidationError="True"
UpdateSourceTrigger="PropertyChanged"
diag:PresentationTraceSources.TraceLevel="High"
Converter="{StaticResource MultiBindingConverter}" >
<Binding Path="Val" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" diag:PresentationTraceSources.TraceLevel="High"></Binding>
<Binding Path="Unit" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" diag:PresentationTraceSources.TraceLevel="High"></Binding>
<MultiBinding.ValidationRules>
<local:ContentControlValidationRule ValidatesOnTargetUpdated="True" x:Name="MValidationRule"/>
</MultiBinding.ValidationRules>
</MultiBinding>
</ContentControl.Content>
</ContentControl>
</Grid>
</Window>
public class ValWithUnits:INotifyPropertyChanged
{
private double m_val;
private int m_unit;
public double Val
{
get => m_val;
set
{
m_val = value;
OnPropertyChanged(nameof(Val));
}
}
public int Unit
{
get => m_unit;
set
{
m_unit = value;
OnPropertyChanged(nameof(Unit));
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public ValWithUnits MyValueWithUnits { get; set; } = new ValWithUnits();
public MainWindow()
{
InitializeComponent();
var a = new Binding("MyValueWithUnits");
a.Source = this;
a.ValidatesOnDataErrors = true;
a.ValidatesOnExceptions = true;
a.NotifyOnValidationError = true;
m_contentControl.SetBinding(ContentControl.ContentProperty, a);
}
public IEnumerable<int> Src => new int[] { 1,2,3};
}
public class ContentControlValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
//Debug.Fail("validate");
return ValidationResult.ValidResult;
}
private static ValidationResult BadValidation(string msg) =>
new ValidationResult(false, msg);
}
public class MultiBindingConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return string.Format("{0}-{1}", values[0], values[1]);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
return new object[] { 1, 1 };
}
}
和代码文件:
<Window x:Class="DELETE1.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:DELETE1"
xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
mc:Ignorable="d"
x:Name="m_win"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<DataTemplate DataType="{x:Type local:ValWithUnits}">
<Border>
<DockPanel>
<ComboBox DockPanel.Dock="Right" Width="60" IsEnabled="True" SelectedIndex="{Binding Unit}" ItemsSource="{Binding Src, ElementName=m_win}" />
<TextBox Text="{Binding Val, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEnabled="True"/>
</DockPanel>
</Border>
</DataTemplate>
<local:MultiBindingConverter x:Key="MultiBindingConverter" />
</Window.Resources>
<Grid>
<ContentControl x:Name="m_contentControl">
<ContentControl.Content>
<MultiBinding Mode="TwoWay" NotifyOnValidationError="True"
UpdateSourceTrigger="PropertyChanged"
diag:PresentationTraceSources.TraceLevel="High"
Converter="{StaticResource MultiBindingConverter}" >
<Binding Path="Val" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" diag:PresentationTraceSources.TraceLevel="High"></Binding>
<Binding Path="Unit" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" diag:PresentationTraceSources.TraceLevel="High"></Binding>
<MultiBinding.ValidationRules>
<local:ContentControlValidationRule ValidatesOnTargetUpdated="True" x:Name="MValidationRule"/>
</MultiBinding.ValidationRules>
</MultiBinding>
</ContentControl.Content>
</ContentControl>
</Grid>
</Window>
public class ValWithUnits:INotifyPropertyChanged
{
private double m_val;
private int m_unit;
public double Val
{
get => m_val;
set
{
m_val = value;
OnPropertyChanged(nameof(Val));
}
}
public int Unit
{
get => m_unit;
set
{
m_unit = value;
OnPropertyChanged(nameof(Unit));
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public ValWithUnits MyValueWithUnits { get; set; } = new ValWithUnits();
public MainWindow()
{
InitializeComponent();
var a = new Binding("MyValueWithUnits");
a.Source = this;
a.ValidatesOnDataErrors = true;
a.ValidatesOnExceptions = true;
a.NotifyOnValidationError = true;
m_contentControl.SetBinding(ContentControl.ContentProperty, a);
}
public IEnumerable<int> Src => new int[] { 1,2,3};
}
public class ContentControlValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
//Debug.Fail("validate");
return ValidationResult.ValidResult;
}
private static ValidationResult BadValidation(string msg) =>
new ValidationResult(false, msg);
}
public class MultiBindingConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return string.Format("{0}-{1}", values[0], values[1]);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
return new object[] { 1, 1 };
}
}
公共类ValWithUnits:INotifyPropertyChanged
{
私人双m_val;
私人国际货币单位;
公共双Val
{
get=>m_val;
设置
{
m_val=值;
OnPropertyChanged(名称(Val));
}
}
公共国际单位
{
get=>m_单位;
设置
{
m_单位=值;
物业变更(单位名称);
}
}
公共事件属性更改事件处理程序属性更改;
[NotifyPropertyChangedInvocator]
受保护的虚拟void OnPropertyChanged(字符串propertyName)
{
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));
}
}
///
///MainWindow.xaml的交互逻辑
///
公共部分类主窗口:窗口
{
public ValWithUnits MyValueWithUnits{get;set;}=new ValWithUnits();
公共主窗口()
{
初始化组件();
var a=新绑定(“MyValueWithUnits”);
a、 来源=此;
a、 ValidateSondaerRors=真;
a、 ValidatesOnExceptions=true;
a、 NotifyOnValidationError=true;
m_contentControl.SetBinding(contentControl.ContentProperty,a);
}
公共IEnumerable Src=>newint[]{1,2,3};
}
公共类ContentControlValidationRule:ValidationRule
{
公共覆盖验证结果验证(对象值,CultureInfo CultureInfo)
{
//调试失败(“验证”);
返回ValidationResult.ValidResult;
}
私有静态验证结果BadValidation(字符串消息)=>
新的ValidationResult(false,msg);
}
公共类MultiBindingConverter:IMultiValueConverter
{
公共对象转换(对象[]值,类型targetType,对象参数,CultureInfo区域性)
{
返回string.Format(“{0}-{1}”,值[0],值[1]);
}
公共对象[]转换回(对象值,类型[]目标类型,对象参数,CultureInfo区域性)
{
返回新对象[]{1,1};
}
}
我通过多重绑定安装的验证“ContentControlValidationRule”无效