3

我无法弄清楚为什么我无法捕获 MS Chart 控件引发的异常。我正在使用带有最新更新的 Visual Studio 2010。感谢您的帮助。

以下是重现问题的方法:

  • 创建一个新的 WinForms 应用程序
  • 添加对 System.Windows.Forms.DataVisualization 的引用
  • 在主窗体上放置一个按钮和一个图表控件
  • 在表单的构造函数中添加以下代码

        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);
    
  • 将以下代码添加到按钮的单击方法中

        try
        {
            chart1.Series[0].Label = "#VAL{";
        }
        catch
        {
            MessageBox.Show("Exception caught");
        }
    
  • 运行应用程序
  • 点击表格上的按钮

上面的 catch 块永远不会执行。相反,标签字符串中使用的无效关键字引发的“InvalidOperationException”会冒泡到应用程序的 Main 方法。

4

2 回答 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 块中重置标签。

于 2012-05-17T11:29:03.797 回答
0

Chart.Area.RecalculateAxesScale()Chart.Refresh()如果由于某种原因不可用,也可以使用。

于 2016-07-12T12:51:58.923 回答