0

我的 xaml 上有很多 TextBox,我在其中实现了 Regex 验证(来自
How to Define TextBox Resctrictions)。在我看来,这采取以下形式:

 <TextBox 
             h:ColorMaskingTextBoxBehavior.Mask="^(?:\d{5})(?:-\d{4})?$"
             Text="{Binding ZipCode}"
            Height="21" HorizontalAlignment="Left" Margin="152,207,0,0"  VerticalAlignment="Top" Width="96"
             />

我不希望限制用户的移动,所以目前验证只是改变了文本框的颜色;红色是一个错误被发现。

收集完所有输入后,用户将单击“保存”以保存窗口。可能涉及正则表达式代码,将它们从 xaml 复制到执行 Save 的视图模型似乎是错误的。

附加的行为如何将文本框标记为无效,以便视图模型只需要在保存窗口之前检查无效标志?我的第一个想法是在文本框上绑定 Tag 依赖属性,但我想知道是否有更好的方法?

任何想法表示赞赏。

TIA

4

1 回答 1

1

我会将所有验证移至视图模型,这就是它的用途。在视图中包含应用程序逻辑并不是一个好的 MVVM 实践。视图应该是可互换的,无需重新编码验证逻辑。然后,您可以使用绑定到视图模型中的属性的样式中的触发器来更改 TextBox 的外观,而不是使用附加的行为。

有些人使用 IDataErrorInfo 接口。我没有。

创建一个视图模型属性,确定 ZipCodeIsValid 是否:

public bool ZipCodeIsValid
{
    get
    {
        var zipCodeRegex = new Regex("^(?:\d{5})(?:-\d{4})?$");
        var zipCodeMatch = zipCodeRegex.Match(ZipCodeText);
        return zipCodeMatch.Success;    
    }
}

每次ZipCodeText属性更改时,都会为属性引发通知属性更改事件ZipCodeIsValid

为您的 TextBox 创建样式:

<Style TargetType="TextBox">
    <Setter Property="Foreground" Value="Black"/>
    <Style.Triggers>
        <DataTrigger Binding="{Binding ZipCodeIsValid}" Value="False">
             <Setter Property="Foreground" Value="Black"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

如果您不想进行那么大的更改并且正在寻找更快的解决方案,您可以将正则表达式字符串移动到静态属性并将它们与附加的行为一起使用,那么您就不会复制正则表达式并且可以使用它们用于测试验证是否通过的视图模型。

使用名为 ZipCode 的静态字符串属性创建一个名为 ValidationRegex 的类:

public class ValidationRegex
{
    public static string ZipCode = "^(?:\d{5})(?:-\d{4})?$";
}

将其与附加行为一起使用:

<TextBox h:ColorMaskingTextBoxBehavior.Mask="{x:Static ValidationRegex.ZipCode}"/>

在您的视图模型中使用它:

public void Save()
{
    var zipCodeRegex = new Regex(ValidationRegex.ZipCode);
    var zipCodeMatch = zipCodeRegex.Match(ZipCodeText);
    if (!zipCodeMatch.Success)
    {
        throw new ValidationException("Zip code is invalid!");
    }
}
于 2015-08-09T22:08:14.210 回答