自定义控件不在设计器中重绘或在属性更改时运行时

时间:2016-11-10 19:23:45

标签: c# .net winforms

我正在创建一个基于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();
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

问题是,当RowsColumns更改时,您不会填充网格单元格边界,因此它们仍为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;
    }
}

并从OnResizeCreatePixelGrid调用它:

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();
}
相关问题