我正在创建一个基于Panel控件的自定义控件,并使用它在其中绘制一个矩形网格。我已将列和行作为属性,以便在控件添加到表单后允许更改它们。但是,如果在设计器或表单代码中更改了值,则永远不会绘制矩形,并且表单显示为空白。我已尝试过不同的建议,例如this.Invalidate()和this.Refresh()在属性的设置部分,但我仍然无法让它绘制新的矩形网格。我确定我在某处遗漏了某些东西。以下是我使用的代码:
public class Pixel
{
public Rectangle Bounds { get; set; }
public bool IsOn { get; set; }
public bool IsSelected { get; set; }
}
public class PixelGridControl : Panel
{
private int columns = 99;
private int rows = 63;
private Pixel[,] pixels;
private bool leftMouseIsDown = false;
private bool rightMouseIsDown = false;
public int Columns
{
get { return columns; }
set
{
if (value > 0)
{
columns = value;
CreatePixelGrid();
this.Refresh();
}
else
{
throw new ArgumentOutOfRangeException("Columns", "Must be > 0");
}
}
}
public int Rows
{
get { return rows; }
set
{
if (value > 0)
{
rows = value;
CreatePixelGrid();
this.Refresh();
}
else
{
throw new ArgumentOutOfRangeException("Rows", "Must be > 0");
}
}
}
public PixelGridControl()
{
this.DoubleBuffered = true;
this.ResizeRedraw = true;
CreatePixelGrid();
}
// adjust each column and row to fit entire client area:
protected override void OnResize(EventArgs e)
{
int top = 0;
for (int y = 0; y < Rows; ++y)
{
int left = 0;
int height = (this.ClientSize.Height - top) / (Rows - y);
for (int x = 0; x < Columns; ++x)
{
int width = (this.ClientSize.Width - left) / (Columns - x);
pixels[x, y].Bounds = new Rectangle(left, top, width, height);
left += width;
}
top += height;
}
base.OnResize(e);
}
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
for (int y = 0; y < Rows; ++y)
{
for (int x = 0; x < Columns; ++x)
{
if (pixels[x, y].IsOn)
{
e.Graphics.FillEllipse(Brushes.Gold, pixels[x, y].Bounds);
e.Graphics.DrawEllipse(Pens.Goldenrod, pixels[x, y].Bounds);
}
else
{
e.Graphics.FillRectangle(Brushes.Black, pixels[x, y].Bounds);
e.Graphics.DrawRectangle(Pens.White, pixels[x, y].Bounds);
}
}
}
base.OnPaint(e);
}
private void CreatePixelGrid()
{
// initialize pixel grid:
pixels = new Pixel[Columns, Rows];
for (int y = 0; y < Rows; ++y)
{
for (int x = 0; x < Columns; ++x)
{
pixels[x, y] = new Pixel();
}
}
}
}
答案 0 :(得分:0)
问题是,当Rows
或Columns
更改时,您不会填充网格单元格边界,因此它们仍为Rectangle.Empty
。
要解决此问题,请将代码从OnResize
移至单独的方法:
private void UpdatePixelGrid()
{
// adjust each column and row to fit entire client area:
int top = 0;
for (int y = 0; y < Rows; ++y)
{
int left = 0;
int height = (this.ClientSize.Height - top) / (Rows - y);
for (int x = 0; x < Columns; ++x)
{
int width = (this.ClientSize.Width - left) / (Columns - x);
pixels[x, y].Bounds = new Rectangle(left, top, width, height);
left += width;
}
top += height;
}
}
并从OnResize
和CreatePixelGrid
调用它:
protected override void OnResize(EventArgs e)
{
UpdatePixelGrid();
base.OnResize(e);
}
private void CreatePixelGrid()
{
// initialize pixel grid:
pixels = new Pixel[Columns, Rows];
for (int y = 0; y < Rows; ++y)
{
for (int x = 0; x < Columns; ++x)
{
pixels[x, y] = new Pixel();
}
}
UpdatePixelGrid();
}