WPF在焦点获取时启动验证

3

我正在开发一个 IDataErrorInfo,用于验证应用程序中的文本框。以下是我的代码:

验证的 .cs 类:

 public class UserInformation : IDataErrorInfo
{
    public string _name;
    public string _surname;

    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }

    public string Surname
    {
        get { return _surname; }
        set { _surname = value; }
    }

    public override string  ToString()
    {
        return Name + " " + Surname;
    }

    public string this[string columnName]
    {
        get
        {
            if (columnName == null) return string.Empty;
            string result = string.Empty;
            if (columnName.Equals("Name"))
            {
                if (string.IsNullOrEmpty(_name))
                    result = "Name cannot be empty.";
            }
            return result;
        }
    }

    public string Error { get; private set; }
}

.xaml文件内容如下:
<TextBox Grid.Column="3" Grid.Row="0" Name="TextBoxName" 
        Style="{DynamicResource InnerTextBox}" 
        Validation.ErrorTemplate="{StaticResource ValidationErrorTemplate}">
        <TextBox.Text>
              <Binding Path="Name" Source="{StaticResource UserInformation}" 
                      ValidatesOnDataErrors="True" UpdateSourceTrigger="PropertyChanged">
                 <Binding.ValidationRules>
                       <ExceptionValidationRule />
                  </Binding.ValidationRules>
                </Binding>
         </TextBox.Text>
      </TextBox>

还有 ErrorTemplate

<ControlTemplate x:Key="ValidationErrorTemplate">
    <DockPanel >
        <StackPanel Orientation="Horizontal" DockPanel.Dock="Top">
            <Grid Width="20" Height="20">
                <Ellipse Width="20" Height="20" Fill="Tomato" HorizontalAlignment="Center" VerticalAlignment="Center" />
                <TextBlock Foreground="White" FontWeight="Heavy" FontSize="8" HorizontalAlignment="Center" VerticalAlignment="Center" TextAlignment="Center"
                   ToolTip="{Binding ElementName=ErrorAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">X</TextBlock>
            </Grid>
            <TextBlock Foreground="Tomato" FontWeight="12" Margin="2,0,0,0" FontSize="20"
                       Text="{Binding ElementName=ErrorAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}" />
        </StackPanel>
        <AdornedElementPlaceholder x:Name="ErrorAdorner" />
    </DockPanel>
</ControlTemplate>

当我输入时,代码运行良好。但是当文本框加载时,验证也会发生。我只希望在失去焦点或更改文本时(例如此处发布的文本)才进行验证。

如何避免在第一次文本框加载时考虑验证错误?

注意:即使我将UpdateSourceTrigger设置为LoseFocus,它仍然进行验证。


我不久之前也遇到了相反的情况。我希望在开始时进行文本框等验证,但由于我使用的是ValidationRule类,所以没有得到工作。对我来说,解决方案是切换到IDataErrorInfo,也许你应该看一下ValidationRules,因为它不会验证直到你开始输入或失去焦点。 - adminSoftDK
你能否请提供一个你所做的例子...?也许? - Sonhja
2个回答

3
为了实现您的目标,您需要执行以下操作:
首先,在绑定中删除ValidatesOnDataErrors="True"。如docs所述:

设置此属性提供了使用DataErrorValidationRule元素的替代方法。

我们将明确使用它。然后,使用DataErrorValidationRule而不是ExceptionValidationRule来正确处理IDataErrorInfo和数据错误。
最后,我们需要使用此规则提供的一些属性:
<Binding.ValidationRules>
    <DataErrorValidationRule ValidatesOnTargetUpdated="False" />
</Binding.ValidationRules>

ValidatesOnTargetUpdated 的值为 false 时,当目标本身发生更改(即在加载时),不会触发验证。您还可以使用 ValidationStep 属性进行额外的控制。

编辑:
好的,我明白了,您需要在加载时跳过验证并且即使值没有更改也需要在失去焦点时进行验证。好吧,验证规则不支持这样做,因为如果值没有更新,则不会调用任何更改事件,也不会进行验证,无论 UpdateSourceTrigger 设置如何。
简单的方法是通过向 TextBox 本身添加 LostFocus 处理程序来模拟此功能:

 private void ValidatedTextBox_LostFocus(object sender, RoutedEventArgs e)
 {
     var txt = (TextBox)sender;
     txt.GetBindingExpression(TextBox.TextProperty).UpdateSource();
 }

如果您需要对多个文本框执行此操作,可以将代码移动到某个静态类中。 使用显式更新源触发器也可以达到相同的效果,这可能会更加简洁。

现在它在加载时没有验证,但在失去焦点时也没有! - Sonhja
好的,我明白了。第一次字段为空时,失去焦点后什么也不会发生。之后我输入并删除一些内容。然后“失去焦点”被激活,验证开始进行。但现在我不知道为什么会这样... - Sonhja
@Sonhja,问题在于 - 如果您不更改值,则无论您使用任何设置和类型,它都不会在焦点丢失时触发验证。请查看我关于该问题的更新。 - icebat

0

目前我没有任何示例,因为我已经转移到了你所拥有的东西。但是你需要创建一个类,该类将继承自系统.windows.controls中存在的ValidationRule,并覆盖Validate方法。

然后你的xaml文本框看起来会像这样

 <TextBox.Text>
<Binding Path="your binding here"    UpdateSourceTrigger="LostFocus" >
  <Binding.ValidationRules>
    <validationClass:yourRule/>  define this at the top of xaml page
  </Binding.ValidationRules>
</Binding>

您应该能够在 MSDN 和这里找到有关验证规则的示例。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接