如何为不断调整大小的面板绘制边框 C#
How to draw border for panel which is continously resizing c#
使用面板作为选择指示器。面板根据 MouseMove 事件上的光标位置更改其大小。但是,当我如下绘制边框时,以前的边框会在面板上留下标记,并且在同一面板内显示太多边框。甚至在每次抽奖前都尝试过 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;
}
首先,您永远不应该在控件绘制处理程序中调用影响控件绘制的方法,例如 Invalidate
或 Refresh
。
修改面板大小后调用Invalidate
或Refresh
即可解决原问题。请注意,最好通过一次调用设置 Size
属性,而不是分别设置 Width
和 Height
:
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();
}
}
更好的选择是将ResizeRedraw property of the selection panel to true
. Since it's a protected
property, you need to create and use your own Panel
subclass. As a bonus, you can also set 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);
}
}
将你的 panel1
设为 SelectionBox
,移除 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));
}
使用面板作为选择指示器。面板根据 MouseMove 事件上的光标位置更改其大小。但是,当我如下绘制边框时,以前的边框会在面板上留下标记,并且在同一面板内显示太多边框。甚至在每次抽奖前都尝试过 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;
}
首先,您永远不应该在控件绘制处理程序中调用影响控件绘制的方法,例如 Invalidate
或 Refresh
。
修改面板大小后调用Invalidate
或Refresh
即可解决原问题。请注意,最好通过一次调用设置 Size
属性,而不是分别设置 Width
和 Height
:
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();
}
}
更好的选择是将ResizeRedraw property of the selection panel to true
. Since it's a protected
property, you need to create and use your own Panel
subclass. As a bonus, you can also set 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);
}
}
将你的 panel1
设为 SelectionBox
,移除 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));
}