无法捕获MS Chart控件异常。

3
我不明白为什么无法捕获MS Chart控件抛出的异常。我使用的是带有最新更新的Visual Studio 2010。感谢你的帮助。
以下是重现问题的方法:
  • Create a new WinForms application
  • Add a reference to System.Windows.Forms.DataVisualization
  • On the main form drop a button and a chart control
  • Add the following code the form's constructor

        int[] x = new int[] { 1, 2, 3, 4, 5 };
        int[] y = new int[] { 5, 13, 4, 10, 9 };
        chart1.Series[0].Points.DataBindXY(x, y);
    
  • Add the following code to the button's click method

        try
        {
            chart1.Series[0].Label = "#VAL{";
        }
        catch
        {
            MessageBox.Show("Exception caught");
        }
    
  • Run the application
  • Click the button on the form
上面的catch块从未执行。相反,由于标签字符串中使用了无效关键字而引发的“InvalidOperationException”将向上冒泡到应用程序的Main方法。

你是不是在另一个线程中执行这个操作? - leppie
不是真的。我提到的问题重现步骤使用标准的单线程winforms应用程序模板。 - veezi
2个回答

2
这种控件的故障模式并不罕见。问题在于Label属性的属性设置器没有执行足够的检查来验证分配的值是否合法。所以当属性值实际被使用时就会出现问题。稍后,当控件绘制自己时,这就会出现错误。在调用堆栈窗口中很容易看到,注意Chart.OnPaint()位于堆栈顶部。调试器停在Application.Run()上,因为那是它实际具有源代码的最后一条语句。所以确保你在调用堆栈中向上查找。
在Winforms中有对此的防范措施,即Application.ThreadException事件将触发。但是在调试时它被关闭了,这是一种帮助你诊断异常的功能。无论如何,ThreadException的事件处理程序也无法修复代码中的错误。你可以捕获异常,但必须强制重绘,以便绘图不会延迟,并且在try块仍然有效时就会出错。
    private void button1_Click(object sender, EventArgs e) {
        try {
            chart1.Series[0].Label = "#VAL{";
            chart1.Refresh();
        }
        catch {
            MessageBox.Show("Exception caught");
        }
    }

但这也不是真正的解决方法,它只会在下一次重绘时再次出现问题。除非你在catch块中重新分配Label属性。唯一真正的解决方法是修复代码。如果允许用户输入标签,则此解决方法应该是有效的,只需确保在catch块中重置标签即可。


图表在 catch 块中重设正确标签后不会刷新。但我猜那是另一个问题了。希望属性设置器执行所需的检查,或者类提供 ValidLabel() 方法。无论如何... - veezi

0

Chart.Area.RecalculateAxesScale()可以在某些情况下无法使用Chart.Refresh()时使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接