当我明确要求控件重绘时,为什么没有捕获绘制异常?
我有一个 GUI 应用程序,它使用 Windows::Forms::DataVisualization::Charting::Chart 显示数据,大多数情况下工作正常。只是偶尔我们会得到一些图表控件不喜欢的虚假数据,从而引发异常。为了尝试捕获导致这些问题的原因,我将重新绘制请求包装在 try/catch 中:
try
{
m_chart->Invalidate();
m_chart->Update();
}
catch(System::Exception^ e)
{
// If something goes wrong during the drawing, we probably want to try
// and record some more information then re-throw it so we can capture
// it properly.
String^ detailString = String::Format("Exception caught while trying to draw raw data. {0}", "Add more debug info here");
throw gcnew System::Exception(detailString, e);
}
...不过出于某种原因,异常不会在那里抛出(我有一个断点和一些日志记录永远不会被击中) - 它发生在其他某个时刻:
Exception:
Value was either too large or too small for a Decimal.
Exception type:
System.OverflowException
Source:
mscorlib
Stack trace:
at System.Decimal..ctor(Double value)
at System.Windows.Forms.DataVisualization.Charting.Axis.RoundedValues(Double inter, Boolean shouldStartFromZero, Boolean autoMax, Boolean autoMin, Double& min, Double& max)
at System.Windows.Forms.DataVisualization.Charting.Axis.EstimateNumberAxis(Double& minimumValue, Double& maximumValue, Boolean shouldStartFromZero, Int32 preferredNumberOfIntervals, Boolean autoMaximum, Boolean autoMinimum)
at System.Windows.Forms.DataVisualization.Charting.Axis.EstimateAxis(Double& minimumValue, Double& maximumValue, Boolean autoMaximum, Boolean autoMinimum)
at System.Windows.Forms.DataVisualization.Charting.Axis.EstimateAxis()
at System.Windows.Forms.DataVisualization.Charting.ChartArea.SetDefaultAxesValues()
at System.Windows.Forms.DataVisualization.Charting.ChartArea.SetData(Boolean initializeAxes, Boolean checkIndexedAligned)
at System.Windows.Forms.DataVisualization.Charting.ChartArea.ReCalcInternal()
at System.Windows.Forms.DataVisualization.Charting.ChartPicture.Paint(Graphics graph, Boolean paintTopLevelElementOnly)
at System.Windows.Forms.DataVisualization.Charting.Chart.OnPaint(PaintEventArgs e)
at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer, Boolean disposeEventArgs)
at System.Windows.Forms.Control.WmPaint(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Installed .net Versions:
v2.0.50727.5420
v3.0.30729.5420
v3.5.30729.5420
v4.0.30319
我在这里错过了什么吗?无效/更新是否不会触发与 Windows 消息泵的其他部分相同的重新绘制?
I have a GUI app which displays data using a Windows::Forms::DataVisualization::Charting::Chart
which works fine most of the time. Just occasionally we get some spurious data which the chart control doesn't like which throws an exception. To try and capture what it is that causes these problems I've wrapped the re-draw request in a try/catch:
try
{
m_chart->Invalidate();
m_chart->Update();
}
catch(System::Exception^ e)
{
// If something goes wrong during the drawing, we probably want to try
// and record some more information then re-throw it so we can capture
// it properly.
String^ detailString = String::Format("Exception caught while trying to draw raw data. {0}", "Add more debug info here");
throw gcnew System::Exception(detailString, e);
}
...for some reason though, the exception isn't thrown there (I have a breakpoint and some logging which never get hit) - it happens at some other point:
Exception:
Value was either too large or too small for a Decimal.
Exception type:
System.OverflowException
Source:
mscorlib
Stack trace:
at System.Decimal..ctor(Double value)
at System.Windows.Forms.DataVisualization.Charting.Axis.RoundedValues(Double inter, Boolean shouldStartFromZero, Boolean autoMax, Boolean autoMin, Double& min, Double& max)
at System.Windows.Forms.DataVisualization.Charting.Axis.EstimateNumberAxis(Double& minimumValue, Double& maximumValue, Boolean shouldStartFromZero, Int32 preferredNumberOfIntervals, Boolean autoMaximum, Boolean autoMinimum)
at System.Windows.Forms.DataVisualization.Charting.Axis.EstimateAxis(Double& minimumValue, Double& maximumValue, Boolean autoMaximum, Boolean autoMinimum)
at System.Windows.Forms.DataVisualization.Charting.Axis.EstimateAxis()
at System.Windows.Forms.DataVisualization.Charting.ChartArea.SetDefaultAxesValues()
at System.Windows.Forms.DataVisualization.Charting.ChartArea.SetData(Boolean initializeAxes, Boolean checkIndexedAligned)
at System.Windows.Forms.DataVisualization.Charting.ChartArea.ReCalcInternal()
at System.Windows.Forms.DataVisualization.Charting.ChartPicture.Paint(Graphics graph, Boolean paintTopLevelElementOnly)
at System.Windows.Forms.DataVisualization.Charting.Chart.OnPaint(PaintEventArgs e)
at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer, Boolean disposeEventArgs)
at System.Windows.Forms.Control.WmPaint(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Installed .net Versions:
v2.0.50727.5420
v3.0.30729.5420
v3.5.30729.5420
v4.0.30319
Have I missed something here? Does invalidate / update not trigger the same re-draw that some other part of the windows message pump does?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
大多数 UI 框架都遵循这种模式。
Invalidate
等只需更新窗口状态中的标志,以便稍后重新绘制。如果您无法捕获绘制代码中的错误,则必须处理
ThreadException
。捕获绘制(或数据绑定)代码中的错误是首选解决方案,但如果您只是临时添加一个处理程序来查看数据是什么,ThreadException
应该可以正常工作。Most UI frameworks follow this kind of pattern.
Invalidate
, etc. just update flags in the window state so that it will be repainted later.If you can't catch the error in the painting code, you'll have to handle
ThreadException
. Catching the error in the painting (or data binding) code is the preferred solution, but if you're just temporarly adding a handler to see what the data is,ThreadException
should work fine.