c# - 在固定位置显示 WPF 验证错误消息

标签 c# wpf validation mvvm

我运行了 WPF 验证(将 ValidationRules 添加到绑定(bind)中)并且使用模板我可以创建漂亮的装饰器。那里有很多帖子。

但我无法找到一种方法来在固定位置(如窗口一角的 TextBlock)显示装饰控件之外的错误消息,例如

我怎样才能做到这一点?我可以将所有验证错误消息绑定(bind)到我的 DataContext(此处为 ViewModel)吗?


更新:多亏了一个答案,我才部分地工作了。验证消息现在显示在另一个标签中。由于所有带有验证规则的文本框都是由代码即时创建的,因此绑定(bind)是这样完成的:

Binding bindSite = new Binding();
bindSite.Source = this.validationErrorDisplayLabel;
BindingOperations.SetBinding(textBox, Validation.ValidationAdornerSiteProperty, bindSite);

但验证消息仅转发到执行此代码的最后一个文本框的 adornersite


我在这个小例子中重现了这个问题。

XAML:

<Grid>
    <TextBox 
        Validation.ValidationAdornerSite="{Binding ElementName=ErrorDisplay}"
        HorizontalAlignment="Left" Height="23" Margin="10,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120">
        <TextBox.Text>
            <Binding>
                <Binding.Path>Box1</Binding.Path>
                <Binding.ValidationRules>
                    <local:RuleA />
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
    </TextBox>
    <TextBox 
        Validation.ValidationAdornerSite="{Binding ElementName=ErrorDisplay}"
        HorizontalAlignment="Left" Height="23" Margin="10,38,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120">
        <TextBox.Text>
            <Binding>
                <Binding.Path>Box2</Binding.Path>
                <Binding.ValidationRules>
                    <local:RuleA />
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
    </TextBox>
    <TextBlock 
        x:Name="ErrorDisplay"
        Background="AntiqueWhite"
        Foreground="Red"
        Text="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.ValidationAdornerSiteFor).(Validation.Errors)[0].ErrorContent}"
        HorizontalAlignment="Left" Margin="230,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" RenderTransformOrigin="2.218,-4.577" Width="177" Height="51"/>
</Grid>

当值等于字符串 "A" 时,类 RuleA 会产生验证错误。第二个文本框中的错误显示在 TextBlock 中,第一个文本框的错误不显示(而是使用默认模板并获得红色边框)。

它如何对两者都起作用?文本 block 不需要汇总所有错误,而是显示第一个错误。

最佳答案

您可以将 BindingGroupValidation.ValidationAdornerSiteValidation.ValidationAdornerSiteFor 属性结合使用。

This blog post向您展示如何执行此操作的示例。


<StackPanel x:Name="FormRoot"
            Validation.ValidationAdornerSite="{Binding ElementName=ErrorDisplay}">
  <FrameworkElement.BindingGroup>
    <BindingGroup Name="FormBindingGroup" />
  </FrameworkElement.BindingGroup>

  <TextBox>
    <TextBox.Text>
      <Binding BindingGroupName="FormBindingGroup"
               UpdateSourceTrigger="LostFocus"
               Path="Box1">
        <Binding.ValidationRules>
          <l:RuleA />
        </Binding.ValidationRules>
      </Binding>
    </TextBox.Text>
  </TextBox>

<TextBox>
    <TextBox.Text>
      <Binding BindingGroupName="FormBindingGroup"
               UpdateSourceTrigger="LostFocus"
               Path="Box2">
        <Binding.ValidationRules>
          <l:RuleA />
        </Binding.ValidationRules>
      </Binding>
    </TextBox.Text>
  </TextBox>

  <ItemsControl x:Name="ErrorDisplay"
                Background="AntiqueWhite"
                Foreground="Red"
                ItemsSource="{Binding RelativeSource={RelativeSource Self},
                                      Path=(Validation.ValidationAdornerSiteFor).(Validation.Errors)}"
                DisplayMemberPath="ErrorContent" />
</StackPanel>

要在用户键入时提交值,请将 UpdateSourceTrigger 值更改为 PropertyChanged。请注意,在这里使用 ValidationAdornerSite 并不是绝对必要的;您可以简单地将 ErrorDisplay 绑定(bind)直接指向 BindingGroup 的所有者:

ItemsSource="{Binding ElementName=FormRoot, Path=(Validation.Errors)}"

关于c# - 在固定位置显示 WPF 验证错误消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26981652/

相关文章:

c# - WPF 自定义控件构造、触发器和事件

c# - Style 和 ControlTemplate 的区别

JavaScript 验证提交时更改值

c# - 使用 Unity 的策略模式和依赖注入(inject)

c# - 将二进制数转换为 ascii 字符

wpf - 如何在 WPF DataGrid 中实现多列 ComboBox DataGridColumn?

javascript - 使 dijit.form.currencytextbox 接受小数点后一位数字的负值

c++ - 检查输入有效性?

c# - ASP.NET MVC3 Controller AOP 代理不拦截所有方法,只有 IController.Execute

c# - 我的 ViewModel 是否具有 Model 的属性和单独的属性?