TextBox验证奇怪的行为

时间:2014-07-01 10:55:50

标签: c# wpf validation xaml

我使用c#在.NET 3.5中使用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?不知道为什么这是有效的?
这是我的TextBoxes的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电话旁边的TextBox时,验证不起作用,直到我将焦点移到页面的其他部分。 TextBox和TextBlocks在StackPanel中,即
StackPanel中
 |
 | - &GT; TextBlock的
 | - &GT;文本框
我希望这是有道理的 的修改
这是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失去焦点时它会被击中。

1 个答案:

答案 0 :(得分:1)

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

至少不在编程和计算机科学中。如果发生了某些事情,那么它只会因为某人实现而发生。你无法得到任何东西。

当您的属性为Int或DateTime时,无异常视图模型有效 - 应该从字符串转换。

您的属性是String - 绑定无法失败并抛出ExceptionValidationRule将处理的异常,因为任何字符串属性都可以轻松绑定到任何字符串属性而无需任何转换。

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

所以:

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:

我忘记了一件事:使用ExceptionValidationRule的异常的WPF引擎处理(实际上是部分错误处理)可能会在调试模式下导致一些问题。独立版本应用程序中没有此类问题。

从此SO thread

  

解决方案不是那么明显,也没有很好的文档记录,但足够简单。   Visual Studio在调试中运行时中断异常的原因   模式是因为它以这种方式配置。

     

在“调试”菜单中,选择“#34;例外...&#34;”。在此对话框中,您可以控制   VS如何处理异常。只需取消选中&#34; User-unhandled&#34;因为&#34;共同   语言运行时例外&#34;,按确定再次运行项目。

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