在活动滚动时绘制面板边框

时间:2013-08-15 04:44:42

标签: c# .net custom-controls panel system.drawing

当我尝试制作面板边框时,我遇到了问题,首先我将我的属性面板设置为:“AutoScroll = true;” 然后我将边框绘图代码放在Panel事件中:

    ControlPaint.DrawBorder(e.Graphics, 
        ClientRectangle,  
        Color.Black, 5, 
        ButtonBorderStyle.Solid,
        Color.Black, 5, ButtonBorderStyle.Solid, 
        Color.Black, 5, ButtonBorderStyle.Solid,
        Color.Black, 5, ButtonBorderStyle.Solid);

实际上我还有第二个问题,我会在这里解释一下..我希望你不介意。 好吧,当面板滚动处于活动状态时,面板边框会出现一些崩溃。看看图片: enter image description here

即使我把

`e.Graphics.TranslateTransform(this.AutoScrollPosition.X, this.AutoScrollPosition.Y);`

它看起来不像边框面板,因为它只是在滚动处于活动状态时在面板内绘制一个矩形。这不是我的预期,但我需要一个边框

我打赌,问题是源代码,这不是因为它不可能,看看 System.Windows.Forms.Panel 我认为它是完美的面板虽然很简单。 请帮我解决这个问题。这让我很困惑

1 个答案:

答案 0 :(得分:4)

这样做不会很好,你正在打击一个名为“拖动时显示窗口内容”的Windows系统选项。它在所有最近的Windows版本中都已打开,您无法合理地将其关闭。该选项的作用是在操作滚动条时以优化的方式滚动窗口内容。它按滚动量复制窗口像素,并要求对滚动显示的窗口部分进行重新绘制。

麻烦的是,这也移动了你画的边框。所以你会看到底部的黑线也会向上移动。但它并没有被删除,因为Windows只要求重新绘制由滚动显示的窗口部分。所以它“涂抹”。顶线刚刚消失,滚动关闭。要解决此问题,您需要重新绘制整个窗口。通过实现面板控件的Scroll事件可以轻松完成:

    private void panel1_Scroll(object sender, ScrollEventArgs e) {
        panel1.Invalidate();
    }

这解决了问题,但您可能仍然会注意到较慢的计算机上的工件。那条黑线仍然向上移动,可以通过Paint事件处理程序再次快速重绘。 “快速”是问题,如果不是那么快,那么你仍然会看到线移动。神器,呃,有趣,你会看到线上做pogo,上下跳跃。人眼对这样的运动非常敏感,能够善于发现高大草原草中的狮子是一种进化优势。

尝试在滚动窗口中保持对象静止不正常。您可以使用面板控件进行操作,并为WM_NCCALCSIZE实现一个消息处理程序,以便为面板提供非客户区域,但这一切都非常痛苦。

简单的解决方案是让Form在面板周围绘制一个矩形:

    protected override void OnPaint(PaintEventArgs e) {
        var rc = panel1.Bounds;
        rc.Inflate(1, 1);
        e.Graphics.DrawRectangle(Pens.Black, rc);
        base.OnPaint(e);
    }

或者更简单,设置面板的BorderStyle。