我如何“捕获”WPF验证错误? [英] How do I 'catch' a WPF validation error?

查看:75
本文介绍了我如何“捕获”WPF验证错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在WPF窗口上有验证问题。



我有一个TextBox,绑定到视图模型中的简单字符串属性。我想确保盒子永远不会是空的。 TextBox 声明如下:



< TextBox x:Name = TextBoxNameValidation.Error =TextBox_Error> 
< TextBox.Text>
< Binding Path =CustomerNameUpdateSourceTrigger =PropertyChangedNotifyOnValidationError =True>
< Binding.ValidationRules>
< u:NonZeroLengthStringValidator />
< /Binding.ValidationRules>
< / Binding>
< /TextBox.Text>
< / TextBox>





正如您所看到的,我已将其设置为更新任务中的字符更改,附加了一个验证错误的事件处理程序,并创建了我自己的验证器来测试空字符串。



如果<$中有一个字符'a' c $ c> TextBox 我将其删除,验证规则返回错误并触发事件。在这种情况下,我弹出一个警告对话框,告诉用户该字段不能为空。我当时想做的是在框中留下最后一个字符'a',因此整个屏幕不需要担心处于无效状态(这会大大增加处理其他字段和控件的复杂性)屏幕)。



我该怎么做?



我尝试过的:



我尝试了很多选项,但我真正的关键点是客户名称设置验证规则失败时,不会调用。这使得支持字段包含单个字符a,而UI显示空框。如果我强制 OnPropertyChanged(CustomerName)更新UI,验证过程会再次运行,我会得到第二个对话框。



因此,总而言之,我几乎让它工作但是我要么得到与支持字段不一致的UI,或者我得到两个错误对话框。



有人能想到这个方法吗?

解决方案

我个人在事件丢失焦点上使用事件触发器来进行string.empty检查。如果字符串为空,那么我用我的默认字符串替换它。我还使用命令属性在视图模型中触发验证,或者您也可以扩展文本框控件中的行为来执行此操作。



事件触发器可以在System.Windows.Interactivity .dll中找到它,如下所示:

 xmlns:i = clr-namespace:System.Windows.Interactivity; assembly = System .Windows.Interactivity 





然后,



< TextBox x:Name =TextBoxNameValidation.Error =TextBox_Error> 
< TextBox.Text>
< Binding Path =CustomerNameUpdateSourceTrigger =PropertyChangedNotifyOnValidationError =True>
< Binding.ValidationRules>
< u:NonZeroLengthStringValidator />
< /Binding.ValidationRules>
< / Binding>
< /TextBox.Text>
< i:Interaction.Triggers>
< i:EventTrigger EventName =LostFocus>
< i:InvokeCommandAction Command = {Binding ElementName = TextBoxName,Path = Datacontext。 YourCommandPropertyHere />
< / i:EventTrigger>
< / i:Interaction.Triggers>
< / TextBox>







另一个解决方案是扩展Textbox使用相同的行为.dll

这里可以找到一个很好的例子,自定义行为


I have a validation problem on a WPF window.

I have a TextBox, bound to a simple string property in the view-model. I want to ensure the box can never be empty. The TextBox is declared as follows:

<TextBox x:Name="TextBoxName" Validation.Error="TextBox_Error" >
    <TextBox.Text>
        <Binding Path="CustomerName" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True">
            <Binding.ValidationRules>
                <u:NonZeroLengthStringValidator/>
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>



As you can see, I have set it to update the source on ever character-change, attached an event handler for validation errors, and created my own validator that tests for an empty string.

If there is a single character 'a' in the TextBox and I delete it, the validation rule returns an error and the event fires. In the event, I pop up a warning dialog, telling the user that the field cannot be empty. What I then want to do is leave the last character 'a' in the box, so the screen as a whole does not need to worry about being in an invalid state (which would hugely increase the complexity of handling the other fields and controls on the screen).

How can I do this?

What I have tried:

I have tried many options, but my real sticking point is that the set on CustomerName is not called when the validation rule fails. This leaves the backing field containing the single character 'a' while the UI shows an empty box. If I force OnPropertyChanged("CustomerName") to update the UI, the validation process runs again and I get a second dialog box.

So, in summary, I almost have it working but I either get the UI out-of-step with the backing field or I get two error dialogs.

Can anyone think of a way round this?

解决方案

I personally use an event trigger on the event lost focus to do a string.empty check. If the string is empty then I replace it with my default string. I also use the command property to fire the validation in the view model, or you can extend a behavior in the textbox control to do this as well.

The event trigger is found in the System.Windows.Interactivity .dll so it is something like:

xmlns:i=clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity



Then,

<TextBox x:Name="TextBoxName" Validation.Error="TextBox_Error" >
    <TextBox.Text>
        <Binding Path="CustomerName" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True">
            <Binding.ValidationRules>
                <u:NonZeroLengthStringValidator/>
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="LostFocus">
             <i:InvokeCommandAction Command={Binding ElementName=TextBoxName, Path=Datacontext.YourCommandPropertyHere/>
         </i:EventTrigger>
    </i:Interaction.Triggers>
</TextBox>




The other solution would be to extend Textbox with a behavior using the same .dll
A good example of how it works can be found here, Custom Behaviors


这篇关于我如何“捕获”WPF验证错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆