WPF 如何在文本框中使用验证规则,而不创建要在对话框中绑定到的额外属性
本文关键字:创建 绑定 对话框 属性 文本 WPF 规则 验证 | 更新日期: 2023-09-27 17:55:29
所以我有一个在这里工作的例子:
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors), Converter={StaticResource ValidationConverter}}"
/>
</Trigger>
<Trigger Property="Validation.HasError" Value="false">
<Setter Property="ToolTip"
Value="GraphPenWidth" />
<Setter Property="Background"
Value="Blue"
/>
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
<TextBox.Text>
<Binding Path="GraphPenWidth" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay">
<Binding.ValidationRules>
<DaedalusValidationRules:IntegerValidationRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
但是,有没有办法在不绑定到数据上下文的情况下使用验证规则?
我正在尝试制作一个通用对话框,我可以将各种验证规则传递给该对话框。但是,一段时间后我发现,即使我在 xaml 中创建验证规则,它也无法正常工作。我读过我可以将文本框的文本属性绑定到自身,但这不起作用。
但是,当我在验证规则中放置断点时,当我插入数据时,它似乎在正确的点被调用。此外,由于背景为蓝色,样式似乎有效。这让我相信Validation.HasError永远不会成为现实,或者正在变成真实,并且变化得如此之快,以至于我看不到变化。
验证规则在我键入的每个字母后都会被调用,但文本框不会更新以显示 haserror = true。 这是为什么呢?
我只是不允许将属性绑定到自身吗? 是否有其他方法可以在没有绑定的情况下使用验证规则,或者我是否总是必须创建一个额外的属性来绑定?最短的修复只是创建一个额外的文本属性并毫无意义地绑定它,但我希望这不是必需的。
<TextBox
Margin="3"
Height="25"
VerticalAlignment="Center"
VerticalContentAlignment="Center"
HorizontalContentAlignment="Left"
Grid.Column="1"
x:Name="MainTextBox"
>
<TextBox.Text>
<Binding RelativeSource="{RelativeSource Self}" Path="Text" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<rules:IntegerValidationRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=(Validation.Errors), Converter={StaticResource ValidationConverter}}"
/>
<Setter Property="Background"
Value="Red"
/>
</Trigger>
<Trigger Property="Validation.HasError" Value="false">
<Setter Property="ToolTip"
Value="Default Signal Height Percentage" />
<Setter Property="Background"
Value="Blue"
/>
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
因此,我实际上设法使验证在 xaml 中工作,只需创建一个属性来绑定 GenericDialogBox 上的名为 Text,然后将该 Text 属性绑定到文本框的文本属性。 但是,我似乎无法在后面的代码中使用相同的代码。
<TextBox.Text>
<Binding Path="Text" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<rules:IntegerValidationRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
但是当我在后面的代码中尝试这样做时,它不起作用。
Binding myBinding = new Binding();
myBinding.Source = this;
myBinding.Path = new PropertyPath("Text");
myBinding.NotifyOnValidationError = true;
myBinding.NotifyOnSourceUpdated = true;
myBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
myBinding.ValidationRules.Add(rule);
MainTextBox.SetBinding(TextBlock.TextProperty, myBinding);
我错过了什么?
尝试将绑定NotifyOnValidationError
设置为 True
,默认情况下为 False:
获取或设置一个值,该值指示是否在验证错误时引发
BindingValidationError
事件。
例:
<Binding NotifyOnValidationError="True" UpdateSourceTrigger="PropertyChanged" ... />
您还可以看到 ValidatesOnDataErrors
属性,当您ViewModel
实现 IDataErrorInfo
接口时会使用他。
代码隐藏的绑定,我在 xaml 中创建了一个绑定,然后在构造函数的代码隐藏中,我获取传递给构造函数的验证规则并将其添加到验证规则中,如下所示:
public GenericDialogBox(string MainLabelContent, string WindowTitle, string TextboxDefaultText, ValidationRule rule)
{
this.DataContext = this;
Text = "";
if (rule != null)
{
TextBoxValidationRule = rule;
}
InitializeComponent();
MainLabel.Content = MainLabelContent;
Title = WindowTitle;
Binding binding = BindingOperations.GetBinding(MainTextBox, TextBox.TextProperty);
binding.ValidationRules.Add(rule);
MainTextBox.SelectAll();
MainTextBox.Focus();
}