Я использую представленное здесь решение, чтобы превратить ошибки привязки в собственные исключения: 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 (строковое сообщение) :
....
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();
}
}
}