控件模板中的验证规则

5

我有一个继承自文本框的控件

public class MyTextBox : TextBox

这有一个样式

<Style TargetType="{x:Type Controls:MyTextBox}">

其中一个 Setter 是

<Setter Property="Template">

我希望能够在模板中设置Binding.ValidationRules,从而影响此类型文本框的所有实例。因此,我可以为数字、日期、邮政编码等创建文本框,或者其他任何我想要的内容。
我不想每次创建文本框时都设置验证规则。我只想说我需要一个NumericTextBox,并且它会按照模板中设置的方式进行验证。
这是可能的吗?
到目前为止,我所看到的都是在控件的每个实例上设置ValidationRules,例如:
<TextBox x:Name="txtEMail" Template={StaticResource TextBoxErrorTemplate}>
<TextBox.Text>
    <Binding Path="EMail" UpdateSourceTrigger="PropertyChanged" >
        <Binding.ValidationRules>
            <local:RegexValidationRule Pattern="{StaticResource emailRegex}"/>
        </Binding.ValidationRules>
    </Binding>
</TextBox.Text>

(来自{{link1:http://www.wpftutorial.net/DataValidation.html}})


该网页介绍了WPF中的数据验证,包括如何使用ValidationRule和IDataErrorInfo接口来实现数据验证。它还解释了如何在XAML中使用数据验证,并提供了一些示例代码。
2个回答

4

正如您所看到的,验证规则是与绑定一起设置的。我曾经遇到过同样的问题,对我有效的解决方案是像这样做:

    public MyTextBox()
    {            
        this.Loaded += new RoutedEventHandler(MyTextBox_Loaded);
    }

    void MyTextBox_Loaded(object sender, RoutedEventArgs e)
    {
        var binding = BindingOperations.GetBinding(this, TextBox.ValueProperty);
        binding.ValidationRules.Add(new MyValidationRule());
    }

这里的问题是在我们添加验证规则之前确保绑定已经设置,因此使用了Loaded,但我不确定这是否适用于每种情况。


嗯,好的。这个怎么与MVVM相配呢?我们应该把这个绑定和验证连接放在代码后面吗?在XAML上进行每个绑定并忽略我所想象的模板化,是否同样容易/难以实现呢? - S Rosam
此方法架构无关,可用于一般验证,否则我看不出从textbox继承创建新类的意义。在您的示例中,您需要检查有效的电子邮件。如果您需要应用程序特定的数据验证,则应始终使用IDataErrorInfo。 - Natxo
是的,我认为在用户控件中,在代码后台拥有代码是可以的。它是一个用户控件,执行特定的任务并可以确保其数据有效。 - S Rosam
这就是了。无论如何,在任何控件中使用CodeBehind并不意味着破坏MVVM,只要它仅用于管理UI即可。 - Natxo

1

我不确定是否可以完全按照您的要求实现。您可能可以在属性设置器中使用许多技巧来实现(我不会依赖此方法,因为它涉及修改绑定,而绑定是动态定义的),或者使用代码后台/自定义控件。

相反,我建议您将验证推入ViewModel中,可能使用IDataErrorInfo。有很多相关文章。这是我刚才搜索“MVVM验证”时找到的第一篇文章之一:

MVVM - Validation

这样做将允许您使用标准的OO组合技术,以便避免重复 :)


我想我会尝试这种方法。 - S Rosam

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