C# 带参数的ValidationRule
我正在用C#和WPF开发一个应用程序,我有自己的滑块自定义控件。和同一窗口上的文本框。我的滑块的所有属性都是C# 带参数的ValidationRule,c#,wpf,validationrules,C#,Wpf,Validationrules,我正在用C#和WPF开发一个应用程序,我有自己的滑块自定义控件。和同一窗口上的文本框。我的滑块的所有属性都是dependencProperty 我使用文本框来更改滑块的属性。我想在文本框上使用ValidationRule。我编写了自己的ValidationRule(派生自ValidationRule类)。我想向该验证规则传递一些参数。以下是代码: 文本框: <TextBox HorizontalAlignment="Left" Height="24" Margin="10,169,0,0"
dependencProperty
我使用文本框来更改滑块的属性。我想在文本框上使用ValidationRule
。我编写了自己的ValidationRule(派生自ValidationRule类)。我想向该验证规则
传递一些参数。以下是代码:
文本框:
<TextBox HorizontalAlignment="Left" Height="24" Margin="10,169,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="40" Style="{DynamicResource archiveSearchTextBox}" MaxLength="3" HorizontalContentAlignment="Center" TabIndex="2">
<TextBox.Text>
<Binding UpdateSourceTrigger="PropertyChanged" Mode="TwoWay" ElementName="gammaSlider" Path="LeftThumbValue" NotifyOnValidationError="True" ValidatesOnExceptions="True" ValidatesOnDataErrors="True">
<Binding.ValidationRules>
<ExceptionValidationRule/>
<local:ZeroTo255MinMax>
<local:ZeroTo255MinMax.Parameters>
<local:ValidationParameters NumberCombineTo="{Binding ElementName=gammaSlider, Path=RightThumbValue}" ValTypeFor0to255="ShouldBeSmaller"/>
</local:ZeroTo255MinMax.Parameters>
</local:ZeroTo255MinMax>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
ZeroTo255MinMax验证规则:
public class ZeroTo255MinMax : ValidationRule
{
private ValidationParameters _parameters = new ValidationParameters();
public ValidationParameters Parameters
{
get { return _parameters; }
set { _parameters = value; }
}
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
string numberStr = value as string;
int val;
if (int.TryParse(numberStr, out val))
{
if (val < 0 || val > 255)
return new ValidationResult(false, "");
else if (Parameters.ValTypeFor0to255 == ValidationParameters.ValTypes.ShouldBeBigger)
{
if (val <= Parameters.NumberCombineTo || val - Parameters.NumberCombineTo < 2)
return new ValidationResult(false, "");
}
else if (Parameters.ValTypeFor0to255 == ValidationParameters.ValTypes.ShouldBeSmaller)
{
if (val >= Parameters.NumberCombineTo || Parameters.NumberCombineTo - val < 2)
return new ValidationResult(false, "");
}
return new ValidationResult(true, "");
}
else
return new ValidationResult(false, "");
}
}
public class ValidationParameters : DependencyObject
{
public enum ValTypes { ShouldBeSmaller, ShouldBeBigger };
public static readonly DependencyProperty NumberCombineToProperty = DependencyProperty.Register("NumberCombineTo", typeof(int), typeof(ValidationParameters), new PropertyMetadata(0, new PropertyChangedCallback(OnNumberCombineToChanged)));
public static readonly DependencyProperty ValTypeFor0to255Property = DependencyProperty.Register("ValTypeFor0to255", typeof(ValTypes), typeof(ValidationParameters), new PropertyMetadata(ValTypes.ShouldBeBigger));
private static void OnNumberCombineToChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { d.CoerceValue(NumberCombineToProperty); }
public int NumberCombineTo
{
get { return (int)GetValue(NumberCombineToProperty); }
set { SetValue(NumberCombineToProperty, value); }
}
public ValTypes ValTypeFor0to255
{
get { return (ValTypes)GetValue(ValTypeFor0to255Property); }
set { SetValue(ValTypeFor0to255Property, value); }
}
}
公共类ZeroTo255MinMax:ValidationRule
{
私有ValidationParameters_parameters=新的ValidationParameters();
公共验证参数
{
获取{返回_参数;}
设置{u参数=值;}
}
公共覆盖验证结果验证(对象值,System.Globalization.CultureInfo CultureInfo)
{
字符串numberStr=作为字符串的值;
int-val;
if(内部TryParse(numberStr,out val))
{
如果(val<0 | | val>255)
返回新的ValidationResult(false)(“”);
else if(Parameters.ValTypeFor0to255==ValidationParameters.ValTypes.shouldbeager)
{
if(val=Parameters.NumberCombineTo | | Parameters.NumberCombineTo-val<2)
返回新的ValidationResult(false)(“”);
}
返回新的ValidationResult(true,“”);
}
其他的
返回新的ValidationResult(false)(“”);
}
}
公共类ValidationParameters:DependencyObject
{
公共枚举值类型{ShouldBeSmaller,shouldbesbiger};
public static readonly dependencProperty NumberCombineToProperty=dependencProperty.Register(“NumberCombineTo”、typeof(int)、typeof(ValidationParameters)、newpropertyMetadata(0,newpropertyChangedCallback(OnNumberCombineToChanged));
public static readonly dependencProperty ValTypeFor0to255Property=dependencProperty.Register(“ValTypeFor0to255”、typeof(ValTypes)、typeof(ValidationParameters)、new PropertyMetadata(ValTypes.shouldbebeager));
NumberCombineTochanged上的私有静态无效(DependencyObject d,DependencyPropertyChangedEventArgs e){d.强制值(NumberCombineToProperty);}
公共国际号码组合
{
获取{return(int)GetValue(NumberCombineToProperty);}
set{SetValue(NumberCombineToProperty,value);}
}
公共值类型值类型0到255
{
获取{return(ValTypes)GetValue(valtypefor0到255property);}
设置{SetValue(ValtypeFor0到255属性,值);}
}
}
我的猜测是,一切正常,但问题是,NumberCombineTo
参数设置为default(0)
,即使我更改了gammaSlider的RightThumbValue属性。
当
RightThumbValue
发生更改时,我需要将NumberCombineTo更新为
属性。我根据您在此处提供的代码片段编写了一个简单完整的代码示例,我相信我能够重现您遇到的基本问题
如果在调试器中运行代码,并查看“输出”窗口,您可能会看到一条消息,其中部分内容如下:
找不到目标元素的治理FrameworkElement或FrameworkContentElement
WPF绑定系统需要这些元素之一才能查找源元素的名称(即ElementName
属性的对象)。但是在这个场景中,您试图绑定一个对象的属性,该对象本身既不是框架相关的元素,也不是WPF可见的元素。因此,它在尝试配置绑定时失败
我看过几篇不同的文章建议通过“代理对象”来解决这个问题。这通常遵循以下模式:声明绑定到包含对象的DataContext
的资源,然后将该对象用作绑定的源。但对我来说,要正确设置它似乎很棘手,这取决于能否设置一个特定的DataContext
对象,该对象包含您实际上想要绑定的属性。随着无框架元素绑定数量的增加,这种技术的应用范围是有限的
例如:
即使在这里
相反,在我看来,这是代码隐藏工作得更好的情况之一。只需几行代码就可以显式地设置绑定,并且完全避免了WPF是否能够找到要绑定的对象的问题
最后我给出了一个XAML示例,如下所示:
<Window x:Class="TestSO28645688ValidationRuleParameter.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestSO28645688ValidationRuleParameter"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:ValidationParameters x:Key="validationParams1"
ValTypeFor0to255="ShouldBeSmaller"/>
</Window.Resources>
<StackPanel>
<Slider x:Name="slider1" Value=".25" />
<Slider x:Name="slider2" Value=".5"/>
<TextBlock Text="{Binding ElementName=slider1, Path=Value,
StringFormat=slider1.Value: {0}}" />
<TextBlock Text="{Binding ElementName=slider2, Path=Value,
StringFormat=slider2.Value: {0}}" />
<TextBlock Text="{Binding Source={StaticResource validationParams1},
Path=NumberCombineTo,
StringFormat=validationParams1.NumberCombineTo: {0}}" />
<TextBox x:Name="textBox1" HorizontalAlignment="Left" VerticalAlignment="Top"
Height="24" Width="400"
Margin="5" TextWrapping="Wrap"
MaxLength="3" HorizontalContentAlignment="Center" TabIndex="2">
<TextBox.Text>
<Binding UpdateSourceTrigger="PropertyChanged" Mode="TwoWay"
ElementName="slider1" Path="Value" NotifyOnValidationError="True"
ValidatesOnExceptions="True" ValidatesOnDataErrors="True">
<Binding.ValidationRules>
<ExceptionValidationRule/>
<local:ZeroTo255MinMax Parameters="{StaticResource validationParams1}"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</StackPanel>
</Window>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Binding binding = new Binding();
binding.Source = slider2;
binding.Path = new PropertyPath(Slider.ValueProperty);
ValidationParameters validationParams = (ValidationParameters)Resources["validationParams1"];
BindingOperations.SetBinding(validationParams, ValidationParameters.NumberCombineToProperty, binding);
}
}
换句话说,它只是创建一个新的绑定
对象,分配源对象和属性,检索要将该对象+属性绑定到的ValidationParameters
对象,然后将ValidationParameters
对象的NumberCombineTo
属性上的绑定设置为
当我这样做时,NumberCombineTo
属性会随着slider2.Value
值的更改而正确更新,并且在调用ValidationRule
对象的Validate()
方法时可以使用它。很难说没有它。你看过调试器的“输出”窗口了吗?是否有任何正在使用的诊断信息?您是否确认绑定到RightThumbValue
在ValidationRule
场景之外工作?你发布的代码对我来说似乎没什么问题,但这并不能说明什么;我在WPF中尝试了很多看起来应该有效的东西,但实际上没有我已经逐行调试了代码RightThumbValue
正在按预期进行更改。我不能