数据绑定在绑定属性中抛出的“隐藏”异常

时间:2009-03-03 06:10:03

标签: c# data-binding exception-handling

我遇到的问题是,我的全局异常处理程序没有捕获从属性集访问器中抛出的异常。

我在一个更大的应用程序中遇到了这个问题,经过多次咬牙切齿解决了我尝试过的问题并成功完成了,在一个更简单的项目中复制了这个问题。

以下是代码和行为。有人可以解释这种行为,以及我应该如何正确编码以实现所需的结果,这是由全局事件处理程序捕获的异常。

//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不会显示抛出异常的消息,即它不会被全局异常处理程序捕获。

如果我通过按钮点击更改属性的值,那么我的处理程序将抛出异​​常,并显示一个消息框。

我错过了什么?

2 个答案:

答案 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
   }
}

我可以将这个处理程序用于所有数据绑定控件。