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);

我错过了什么?

WPF 如何在文本框中使用验证规则,而不创建要在对话框中绑定到的额外属性

尝试将绑定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();
    }