我在 .NET 3.5 中使用 C# 开发了 WPF 应用程序。
目前该应用程序使用了大量代码隐藏方法,它是在我开始处理它之前开发的,我想删除所有代码隐藏方法并使用 WPF 验证文本框。当前验证发生在控制丢失时,它是焦点,即
private void Control_LostFocus(object sender, RoutedEventArgs e)
现在我关注了这个tutorial在验证上,在我的应用程序中实现验证后,我得到了这些结果:
如您所见,验证未获取 TextBox 的更改,但是当我尝试这样做时:
验证成功。
当我这样做时它也是成功的:
不知道为什么这是有效的?
这是我的文本框的 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:
以下是情况的屏幕截图:
没有输入,字段无效
字段应有效但验证失败:-(
控件失去焦点并进行验证!?
注意:
当 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/