Draw Border of Panel When it is being Active Scroll

隐身守侯 提交于 2020-07-09 14:25:08

问题


I just got problem when i'm trying to make a panel border, firstly i have set my properties panel to be: "AutoScroll = true;" then i put the border drawing codes in Panel event:

    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);

actually i still got a second problem and i will explain it all here.. I hope you don't mind. well, the panel border will get some crash when the panel scroll is being active. take a look at the picture: enter image description here

even i put

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

it doesn't looks like a border panel because it just draw a rectangle inside panel when the scroll is being active. that's not what i expected, but i need a Border

i bet, the problem is the source code, that is not because it is not possible, take a look at System.Windows.Forms.Panel i think it is perfect panel although it simple. please help me to solve this problem. this has made me confused


回答1:


This is not going to work well, you are fighting a Windows system option named "Show window contents while dragging". It is turned on in all recent Windows versions and you cannot reasonably turn it off. What the option does is scroll the window content in an optimized way when you operate the scrollbar. It copies the window pixels by the scroll amount and asks for a repaint for the part of the window that got revealed by the scroll.

Trouble is, that also moved your painted border. So you'll see the black line in the bottom getting moved up as well. But it doesn't get erased because Windows asked only for a repaint of the part of the window that got revealed by the scroll. So it "smears". The top line just disappears, getting scroll off. To get this fixed, you need to repaint the entire window. Easy to do by implementing the Scroll event for the panel control:

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

That fixes the problem, but you may still notice an artifact on slower machines. That black line is still getting moved up, to be quickly overpainted again by your Paint event handler. The "quickly" is the issue, if it is not that quickly then you'll still see that line move. The artifact is, erm, interesting, you'll see the line doing the pogo, jumping up and down. The human eye is very sensitive to motion like that, it was an evolutionary advantage to be able to be good at detecting the lion in the tall savanna grass.

Trying to keep objects stationary in scrolling window just doesn't work that well. You can monkey with the panel control and implement a message handler for WM_NCCALCSIZE to give the panel a non-client area but that's all rather painful.

The simple solution is to just have the Form draw a rectangle around the panel:

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

Or easier yet, set the panel's BorderStyle.



来源:https://stackoverflow.com/questions/18246467/draw-border-of-panel-when-it-is-being-active-scroll

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!