c# - 文本框验证奇怪的行为

标签 c# wpf validation xaml

我在 .NET 3.5 中使用 C# 开发了 WPF 应用程序。
目前该应用程序使用了大量代码隐藏方法,它是在我开始处理它之前开发的,我想删除所有代码隐藏方法并使用 WPF 验证文本框。当前验证发生在控制丢失时,它是焦点,即

private void Control_LostFocus(object sender, RoutedEventArgs e)

现在我关注了这个tutorial在验证上,在我的应用程序中实现验证后,我得到了这些结果:
validation not picking up changes 如您所见,验证未获取 TextBox 的更改,但是当我尝试这样做时:
Second letter triggers validation 验证成功。
当我这样做时它也是成功的:
empty field seems valid?不知道为什么这是有效的?
这是我的文本框的 xaml:

<TextBox
    MaxLength="20"
    VerticalAlignment="Top" 
    VerticalContentAlignment="Center" 
    Width="120" Template="{DynamicResource TextBoxControlTemplate}" TabIndex="6" >
    <TextBox.Text>
       <Binding Path="Order.HirerName" UpdateSourceTrigger="PropertyChanged">
           <Binding.ValidationRules>
               <ExceptionValidationRule/>
           </Binding.ValidationRules>
       </Binding>
    </TextBox.Text>
<!-- OLD VALIDATION METHODS -->
<!--GotFocus="Control_GotFocus"
    KeyUp="Control_KeyUp"
    LostFocus="Control_LostFocus"-->
<TextBox.BorderBrush>
    <SolidColorBrush Color="Green"/>
</TextBox.BorderBrush>
</TextBox>  

我的问题是:为什么结果如此不同且不一致。有时我必须单击另一个 TextBox 或任何其他可以获得焦点的控件来强制验证。
注意
当我单击 Hirer Telephone 旁边的 TextBox 时,在我将焦点移到页面的其他部分之前,验证不起作用。 TextBox 和 TextBlocks 在 StackPanel 中,即
堆叠面板
|
|->文本 block
|->文本框
我希望这是有道理的。
编辑
这是 HirerName 属性:

public string HirerName
    {
        get { return _HirerName; }
        set
        {
            if (!string.Equals(_HirerName, value, StringComparison.Ordinal))
            {
                _HirerName = value;
                OnPropertyChanged(new PropertyChangedEventArgs("HirerName"));
            }
        }
    }

编辑 2:
以下是情况的屏幕截图:
Initial state
没有输入,字段无效
Key Pressed
字段应有效但验证失败:-(
Lost focus
控件失去焦点并进行验证!?
注意:
当 Control 失去焦点时,Order 上的字段会再次更新,即我在我的属性上设置了断点,当 Control 失去焦点时它被击中。

最佳答案

好吧,我仍然认为自己年轻,但我不相信魔法。

至少在编程和计算机科学中不是。如果某件事发生了,那么它的发生只是因为有人让它发生了。你不能不劳而获。

当您的属性是 Int 或 DateTime 时,No-exception-in-viewmodel 起作用 - 应该从字符串转换而来的东西。

您的属性是 String - 绑定(bind)不可能失败并抛出 ExceptionValidationRule 的异常将处理,因为任何字符串属性无需任何转换即可轻松绑定(bind)到任何字符串属性。

WPF 对您对 HirerName 正确性的要求一无所知。所以它允许任何东西作为有效值传递给 setter 。这是您的属性(property),应该对任何不正确的数据做出积极 react 。

所以:

public string HirerName
    {
        get { return _HirerName; }
        set
        {
            if (String.IsNullOrEmpty(value)
                 throw new ArgumentException("Null or empty");

            if (value.Length < 3)
                 throw new ArgumentException("Too short");

            if (!string.Equals(_HirerName, value, StringComparison.Ordinal))
            {
                _HirerName = value;
                OnPropertyChanged(new PropertyChangedEventArgs("HirerName"));
            }
        }
    }

关于UnhandledException:

我忘记了一件事:WPF 引擎使用 ExceptionValidationRule 处理(实际上是部分错误处理)异常可能会在 Debug模式下导致一些问题。单机版应用不存在此类问题。

从这里SO thread :

The solution is not so obvious nor well documented, but simple enough. The reason Visual Studio breaks for exceptions when running in debug mode is because it's configured that way.

In the Debug menu, select "Exceptions...". In this dialog you control how VS handles exceptions. Simply uncheck "User-unhandled" for "Common Language Runtime Exceptions", press OK and run your project again.

P.S.:如果我记得有更好的处理方法,那么我会在这里添加。

关于c# - 文本框验证奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24508532/

相关文章:

Java Swing 验证

javascript - 如何使用 bootstrap 验证表单的字数和字母数字值

c# - 如何在 Microsoft Graph 中使用 DI

c# - 如何在C#中动态添加数组的索引值?

c# - 解决我的服务层中的依赖关系

wpf - 为什么绑定(bind)对 ICommand 属性进行特殊处理?

c# - 当用户在 wpf 中将鼠标悬停在它上面时,我如何突出显示它?

java - 如何确定文件是否为 PDF 文件?

c# - ASP.MVC 中包含多个分部 View 的复杂 View

c# - 将 XAML 网格绑定(bind)到数组