BindingExpression.UpdateSource swallows exception
The following code snippet is a simplified version of my issue. Basically I'm trying to catch开发者_StackOverflow中文版 the error that occurs in my setter when updatesource is called and propagate it up to my the catch block shown below. The problem is if an exception occurs in the call stack below updatesource, BindingExpression.UpdateSource() seems to catch that error and handle it. I can't get the exception to make it back out to my catch statement. Can this behavior be disabled?
BindingExpression be = textBox.GetBindingExpression(TextBox.TextProperty);
try
{
be.UpdateSource();
}
catch (Exception ex)
{
MessageBox.Show("ex.Message");
}
//////////////////////////////////////////////////////////////////
public string MyValue
{ get {return _value;}
set {
if(value > 10)
throw new Exception("Out of Range");
}
}
Binding in WPF and Silverlight can be configured to use exceptions thrown in the setter for validation. I believe Donut's comment about ValidatesOnExceptions is at the heart of the issue. The other related attribute (at least in Silverlight) is NotifyOnValidationError. If you aren't using this feature for validation you should be able to turn it off. If you are, you might be able to get it from from the validation system.
EDIT: I made a sample project to check out the situation, and while stepping through I found that UpdateSource() catches the exception for the purpose of the validation system, and it appears that it doesn't rethrow. You could create your own UpdateSource method (perhaps as an extension method with a different name) that updates the value of the property in the binding, but doesn't catch the exception (or catches and rethrows).
I know this is a really old topic, but just stumbled upon it.
This article provides a really nice way of catching errors that occur inside the setters: https://wpf.2000things.com/2017/06/18/1211-catching-exceptions-originating-in-property-accessors/
How it works is extremely simple and effective: it creates an override of TraceListener and re-throws the exception inside the overriden WriteLine() method. Then, App.OnStartup() it adds the new Listener to PresentationTraceSources.DataBindingSource.Listeners and all of a sudden, the exception being thrown inside the setter can be caught.
The drawback is that if you have any binding errors throughout your application, these will be caught immediately and you'll start seeing them.
精彩评论