2

我的应用程序弹出一个表单作为主表单的子表单。表单上是
用户控件,其中包含呈现图形的面板。当在调试模式下从 Visual Studio 执行时,绘图通常按预期呈现,想象一个简单的 XY 图形。如果面板的图形没有被绘制,那么在绘图例程中添加两个或三个断点通常可以解决问题。

当在 Visual Studio 中以发布模式执行时,或在任何模式下从 .exe 执行时,图形永远不会呈现,尽管调用了用户控件的 Paint 方法。当然,调整表单大小会导致重新调用重新绘制,并且现在可以正确渲染图像。

谁能给我一些见解,为什么调试和发布模式之间的行为存在差异,从 VS 内部和外部 VS 执行,为什么断点有时会修复问题?以及如何使图形始终可见。

谢谢,

瑞克

替代文字 http://img160.imageshack.us/my.php?image=profilebeforeresizeti4.png替代文字 http://img512.imageshack.us/my.php?image=profileafterresizenw2.png

4

2 回答 2

1

如果没有更多信息,我无法确定您看到行为差异的原因(我建议您看到同样的问题,因为您承认调试版本也不总是有效),但您可能会发现断点会通常“修复”绘画问题,因为切换回 Visual Studio 最终会使整个绘画表面无效,而不仅仅是一小部分。因此,您启动了应用程序并且它没有正确绘制,您在 Visual Studio 中打了一个断点,切换查看一些变量,返回到应用程序并正确绘制,因为使用正确的剪切矩形调用 OnPaint 以重新绘制整个表面(通常也调用 OnPaintBackground,见下文)。

如果是这种情况,您应该能够通过最小化和恢复您的应用程序在发布版本中复制它。如果这“修复”了您的控件的显示,那么它可能是由您的绘制方法的问题引起的,假设它可能不是绘制整个控件。

您还可以查看 PaintBackground 以确保正确擦除控件的表面。您可能要离开旧显示器,然后在其上重新绘制,而不是从“新”画布开始。

根据您对正在发生的事情的描述以及重绘的方式,这些是我最好的建议。我需要一些更具体的细节(绘制代码、所发生情况的具体描述 - 控件是未绘制还是仅显示部分等)以提供更准确的帮助。

于 2008-11-14T06:49:57.890 回答
1

我只是试了一下,它在发布模式下达到了我的预期。. . 它用蓝色和一个大黄色椭圆填充面板。请发布重现问题所需的最少示例代码。. . 也许在下面的 MyPanel 基础上构建。

计时器的作用是确保我们不会过于频繁地重绘。这是一个自动终止计时器,它强制重新绘制整个控件。这是必需的,因为自定义绘制的内容大小与控件有关。

   public class MyPanel : Panel
    {
        Timer _resizeRedrawDelayTimer = new Timer();
        public MyPanel()
        {
            _resizeRedrawDelayTimer.Interval=50;
            _resizeRedrawDelayTimer.Tick += new EventHandler(_resizeRedrawDelayTimer_Tick);
        }

        void _resizeRedrawDelayTimer_Tick(object sender, EventArgs e)
        {
            Invalidate();
            _resizeRedrawDelayTimer.Stop();
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            // don't redraw if still resizing.
            if (!_resizeRedrawDelayTimer.Enabled)
            {
                e.Graphics.FillRectangle(Brushes.Blue, this.ClientRectangle);
                e.Graphics.FillEllipse(Brushes.Yellow, this.ClientRectangle);
            }
            base.OnPaint(e);
        }

        protected override void OnResize(EventArgs eventargs)
        {
            if (_resizeRedrawDelayTimer.Enabled)
                _resizeRedrawDelayTimer.Stop();
            // restart the timer.
            _resizeRedrawDelayTimer.Start();
            base.OnResize(eventargs);
        }
    }
于 2009-11-25T06:03:47.650 回答