如何使用附加行为将文本框输入标记为无效

时间:2015-08-08 05:11:02

标签: wpf xaml mvvm attachedbehaviors

我的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的viewmodel似乎是错误的。

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

任何想法都表示赞赏。

TIA

1 个答案:

答案 0 :(得分: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!");
    }
}