简体   繁体   English

如何为连续调整C#的面板绘制边框

[英]How to draw border for panel which is continously resizing c#

Using panel as a selection indicator . 使用面板作为选择指示器。 The panel changes its size according to cursor position on MouseMove event . 面板根据MouseMove事件上的光标位置更改其大小。 However when I draw the border as below , previous borders leave their mark on the panel and it displays too many border within same panel . 但是,当我按如下所示绘制边框时,以前的边框会在面板上留下标记,并且同一面板内显示的边框太多。 Even tried refresh() before every draw but that makes it glitchy and slow 甚至在每次抽奖之前都尝试过refresh(),但这会使它出现故障和缓慢

private void panel1_Paint(object sender, PaintEventArgs e)
{
    this.panel1.Refresh();
    ControlPaint.DrawBorder(e.Graphics, this.panel1.ClientRectangle, Color.DarkBlue, ButtonBorderStyle.Solid);
}

private void drawboard_MouseMove(object sender, MouseEventArgs e)
{
    panel1.Width = e.Location.X - panel1.Left;
    panel1.Height = e.Location.Y - panel1.Top;        
}

First off, you should never call control paint affecting methods like Invalidate or Refresh inside the control paint handler. 首先,永远不要在控件绘画处理程序中调用影响控件绘画的方法,例如InvalidateRefresh

You can solve the original issue by calling Invalidate or Refresh after modifying the size of the panel. 您可以在修改面板大小后通过调用InvalidateRefresh来解决原始问题。 Note that it's better to set the Size property with one call rather than Width and Height separately: 请注意,最好只调用一次来设置Size属性,而不要分别设置WidthHeight

private void panel1_Paint(object sender, PaintEventArgs e)
{
    ControlPaint.DrawBorder(e.Graphics, this.panel1.ClientRectangle, Color.DarkBlue, ButtonBorderStyle.Solid);
}

private void drawboard_MouseMove(object sender, MouseEventArgs e)
{
    var size = new Size(Math.Max(e.Location.X - panel1.Left, 0), 
        Math.Max(e.Location.Y - panel1.Top, 0));
    if (panel1.Size != size)
    {
        panel1.Size = size;
        panel1.Invalidate();
    }
}

A better option is to set ResizeRedraw property of the selection panel to true . 更好的选择是将选择面板的ResizeRedraw属性设置为true Since it's a protected property, you need to create and use your own Panel subclass. 由于它是一个protected属性,因此您需要创建和使用自己的Panel子类。 As a bonus, you can also set DoubleBuffered property to true to avoid the flickering, and also move the painting code inside: 另外,您还可以将DoubleBuffered属性设置为true以避免闪烁,还可以在内部移动绘画代码:

class SelectionBox : Panel
{
    public SelectionBox()
    {
        ResizeRedraw = true;
        DoubleBuffered = true;
    }
    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        ControlPaint.DrawBorder(e.Graphics, ClientRectangle, Color.DarkBlue, ButtonBorderStyle.Solid);
    }
}

Make your panel1 to be SelectionBox , remove the Paint event handler, and then the mouse move handler could be simple 使您的panel1SelectionBox ,删除Paint事件处理程序,然后鼠标移动处理程序可能很简单

private void drawboard_MouseMove(object sender, MouseEventArgs e)
{
    panel1.Size = new Size(Math.Max(e.Location.X - panel1.Left, 0), 
        Math.Max(e.Location.Y - panel1.Top, 0));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM