更改标签时WPF验证停止工作 我已经尝试了两种解决方法listed here,但是它们似乎没有带红色边框:

问题描述

我有一个WPF应用程序,其中有一个TabControl,并且在某个选项卡中有一个带有验证规则的TextBox

验证规则工作正常,转换器工作正常,绑定也可以。
但是当我这样做时,会发生一个非常烦人的错误(可能是WPF本身):

  • 输入无效的文本(验证发生,文本框显示红色边框)
  • 更改为另一个标签
  • 返回带有文本框的标签

直到我输入 valid 文本,验证才完全停止工作,然后再次开始工作。 更改文本是不够的,只有输入有效的文本,它才能重新开始工作。

进入标签页后,如何强制重新验证文本?


我已经尝试了两种解决方法listed here,但是它们似乎没有带红色边框:

  • 在选项卡上的事件Selector.Selected中(检查是否正在调用它),添加txtName.GetBindingExpression(TextBox.TextProperty).UpdateSource();
  • 在验证规则中使用ValidatesOnTargetUpdated="True"属性

如果需要,这是XAML的简要说明:

<TabControl ...>
    <TabItem ... />
    <TabItem ...>
        ...
        <TextBox Name="txtName" ...>
            <TextBox.Text>
                <Binding Path="..." 
                         UpdateSourceTrigger="PropertyChanged" 
                         Mode="OneWayToSource"
                         FallbackValue="5"
                         Converter="MyCustomConverterWorkingOk">

                     <Binding.ValidationRules>
                         <local:MyCustomValidationWorkingOk/>
                     </Binding.ValidationRules>
                </Binding> 
            </TextBox.Text>
        </TextBox>
    </TabItem>
</TabControl>

解决方法

此行为的原因是TabControl显示其内容的方式:所有选项卡共享相同的ContentPresenter。在选项卡之间导航时,旧内容将被完全删除。对于在其上呈现错误模板的AdornerLayer也是如此。由于AdornerLayer是无状态的,并且TabControl不能监视所有可能的修饰符,因此无法还原先前选项卡内容的旧渲染错误模板。

您有三个不错的选择:

  1. 除非标签的数据处于有效状态,否则不允许用户离开标签
  2. 离开标签页时
  3. 丢弃无效数据(这也会重置相关错误)
  4. 切换回包含无效数据输入的AdornerLayer时,强制TabItem重新渲染。

以下示例显示了如何在装饰元素可见后立即强制AdornerLayer渲染所有TextBox元素的装饰物:

<!-- Custom error template -->
<ControlTemplate x:Key="ValidationErrorTemplate">
  <StackPanel>

    <!-- Placeholder for the TextBox itself -->
    <AdornedElementPlaceholder />

    <TextBlock Text="{Binding ErrorContent}"
               Foreground="Red" />
  </StackPanel>
</ControlTemplate>

<!-- Style to trigger the rendering of the AdornerLayer by setting the error template -->
<Style TargetType="TextBox">
  <Setter Property="Validation.ErrorTemplate"
          Value="{x:Null}" />
  <Style.Triggers>
    <MultiTrigger>
      <MultiTrigger.Conditions>
        <Condition Property="Validation.HasError"
                   Value="True" />
        <Condition Property="IsVisible"
                   Value="True" />
      </MultiTrigger.Conditions>
      <Setter Property="Validation.ErrorTemplate"
              Value="{StaticResource ValidationErrorTemplate}" />
    </MultiTrigger>
  </Style.Triggers>
</Style>
,

不确定,请尝试以下操作:

string text = txtName.Text;
txtName.Text = null;
txtName.Text = text;