【问题标题】:Databound numericupdown 'hiding' exceptiong thrown in bound property绑定属性中引发的数据绑定 numericupdown“隐藏”异常
【发布时间】:2009-03-03 06:10:03
【问题描述】:

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

我在一个更大的应用程序中遇到了这个问题,经过大量的牙齿故障排除后,我尝试并成功地在一个更简单的项目中复制了这个问题。

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

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

相反,如果我通过单击按钮更改属性的值,则会引发异常并被我的处理程序捕获,并显示一个消息框。

我错过了什么?

【问题讨论】:

    标签: c# data-binding exception-handling


    【解决方案1】:

    绑定将“吞下”或“隐藏”异常。这大概是为了更容错。

    您需要监听 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;
            }
        }
    

    【讨论】:

      【解决方案2】:

      谢谢穆法卡

      这非常有帮助,让我进一步扩展了数据绑定方面的知识。然而,异常仍然没有被全局异常处理程序捕获。代码在 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
         }
      }
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-19
        • 1970-01-01
        • 2011-04-22
        • 2013-10-17
        • 2020-02-14
        • 2013-04-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多