我遇到的问题是,我的全局异常处理程序没有捕获从属性集访问器中抛出的异常。
我在一个更大的应用程序中遇到了这个问题,经过多次咬牙切齿解决了我尝试过的问题并成功完成了,在一个更简单的项目中复制了这个问题。
以下是代码和行为。有人可以解释这种行为,以及我应该如何正确编码以实现所需的结果,这是由全局事件处理程序捕获的异常。
//Program.cs - Wire up global exception handling
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
Application.Run(new Form1());
}
static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
MessageBox.Show("Exception occured : " + e.Exception.Message);
}
*
//In main form create instance of class containing bound property and setup databinding
//to numericUpDown control
private void Form1_Load(object sender, EventArgs e)
{
_car = new Car();
_car.NumberOfWheels = 4;
numericUpDown1.DataBindings.Add(new Binding("Value", _car, "NumberOfWheels", true, DataSourceUpdateMode.OnPropertyChanged));
}
*
public int NumberOfWheels
{
get { return _numberOfWheels; }
set
{
if (value < 4)
//Throw some exception
throw new ArgumentNullException("Argument null exception trigger in Number Of Wheels property");
_numberOfWheels = value;
}
}
如果我在'throw new ArgumentNullException'行设置一个断点,当我更改numericUpDown控件的值(绑定到NumberOfWheels属性)时,程序肯定会在此时断开。但是,这是检测是否抛出异常的唯一方法。通过UI不会显示抛出异常的消息,即它不会被全局异常处理程序捕获。
如果我通过按钮点击更改属性的值,那么我的处理程序将抛出异常,并显示一个消息框。
我错过了什么?
答案 0 :(得分:0)
绑定将“吞噬”或“隐藏”异常。据推测,这可能是更容错的。
您需要侦听BindingComplete事件并检查BindingCompleteEventArgs BindingCompleteState属性上的BindingCompleteState。如果该值为BindingCompleteState.Exception,则BindingCompleteEventArgs Exception属性将包含抛出的异常。
public Form1()
{
InitializeComponent();
Binding binding = new Binding("Value", _car, "NumWheels", true, DataSourceUpdateMode.OnPropertyChanged);
numericUpDown1.DataBindings.Add(binding);
binding.BindingComplete += new BindingCompleteEventHandler(binding_BindingComplete);
}
void binding_BindingComplete(object sender, BindingCompleteEventArgs e)
{
if (e.BindingCompleteState == BindingCompleteState.Exception)
{
throw e.Exception;
}
}
答案 1 :(得分:0)
感谢Mufaka
这非常有用,让我可以进一步扩展我对数据绑定的了解。但是,异常仍未被全局异常处理程序捕获。代码在binding_BindingComplete的最后一个'}处断开,并显示“ArgumentNullException未被用户代码处理”。
我能描述的唯一方法就是设置
binding.FormattingEnabled = false;
但这似乎有它自己的问题。
我认为我现在要做的是采取你的方法,但不是再次抛出异常,我会显示一个消息框并恢复原始值。
private void binding_BindingComplete(object sender, BindingCompleteEventArgs e)
{
if (e.BindingCompleteState == BindingCompleteState.Exception)
{
MessageBox.Show(e.Exception.Message);
e.Binding.ReadValue(); //resets value to actual value of data source instead of leaving it as changed value of control
}
}
我可以将这个处理程序用于所有数据绑定控件。