我使用此处介绍的解决方案将绑定错误转化为原生异常:http://www.jasonbock.net/jb/Default.aspx?blog=entry.0f221e047de740ee90722b248933a28d
但是,WPF 绑定中的一个正常情况是在用户输入无法转换为目标类型的情况下引发异常(例如,绑定到整数字段的 TextBox;非数字字符串的输入会导致FormatException,输入的数字太大导致OverflowException)。类似的情况是源属性的 Setter 抛出异常。
处理此问题的 WPF 方法是通过 ValidatesOnExceptions=true 和 ValidationExceptionRule 向用户发出所提供的输入不正确的信号(使用异常消息)。
但是,这些异常也会发送到输出窗口,因此被 BindingListener “捕获”,从而导致错误...显然不是您想要的行为。
因此,我扩展了 BindingListener 类以在这些情况下不抛出异常:
private static readonly IList<string> m_MessagesToIgnore =
new List<String>()
{
//Windows.Data.Error 7
//Binding transfer from target to source failed because of an exception
//Normal WPF Scenario, requires ValidatesOnExceptions / ExceptionValidationRule
//To cope with these kind of errors
"ConvertBack cannot convert value",
//Windows.Data.Error 8
//Binding transfer from target to source failed because of an exception
//Normal WPF Scenario, requires ValidatesOnExceptions / ExceptionValidationRule
//To cope with these kind of errors
"Cannot save value from target back to source"
};
public override void WriteLine(string message)中的修改行:
....
if (this.InformationPropertyCount == 0)
{
//Only treat message as an exception if it is not to be ignored
if (!m_MessagesToIgnore.Any(
x => this.Message.StartsWith(x, StringComparison.InvariantCultureIgnoreCase)))
{
PresentationTraceSources.DataBindingSource.Listeners.Remove(this);
throw new BindingException(this.Message,
new BindingExceptionInformation(this.Callstack,
System.DateTime.Parse(this.DateTime),
this.LogicalOperationStack, int.Parse(this.ProcessId),
int.Parse(this.ThreadId), long.Parse(this.Timestamp)));
}
else
{
//Ignore message, reset values
this.IsFirstWrite = true;
this.DetermineInformationPropertyCount();
}
}
}