ContainerControl无法正确地在Scroll上绘制控件

时间:2014-10-11 18:05:41

标签: c# containers

我有一个自定义CheckListBox控件假设的功能与CheckedListBox控件相同,但事实并非如此。问题是当我向下滚动时,绘图会搞得一团糟。容器实际上不会向下滚动,它只是“抖动”周围的复选框,绘制随机线等。

更新:我更改了代码,因此在CheckBox方法中设置了每个OnControlAdded的位置,而不是OnPaint方法。它现在滚动很好,但绘图仍然搞砸了!边框丢失,BackColor更改,复选框的行不直;只是一堆乱七八糟的东西。它在设计师(滚动和绘图)中完美运行,但在我运行程序时则不行。

enter image description here

以下是控件的代码:

public class ChromeCheckListBox : ChromeContainerControl
{
    [Description("Determines what corner(s) will be rounded.")]
    public Utilities.RoundedRectangle.RectangleCorners Corners { get; set; }

    private int cornerRadius;
    [Description("Determines the radius of the the corners")]
    public int CornerRadius
    {
        get { return cornerRadius; }
        set
        {
            if (value < 1)
                Utilities.ThrowError("The radius cannot be less than 1. If you want no radius, set Corners to None.");
            else
                cornerRadius = value;
        }
    }

    [Description("Determines the list of ChromeRadioButton controls that are displayed.")]
    private ChromeCheckBox[] items;
    public ChromeCheckBox[] Items
    {
        get { return items; }
        set
        {
            items = value;
            Controls.Clear();
            Controls.AddRange(items);
        }
    }

    public ChromeCheckListBox()
    {
        this.AutoScroll = true;
        this.Corners = Utilities.RoundedRectangle.RectangleCorners.All;
        this.CornerRadius = 1;
        this.Items = new ChromeCheckBox[0];
        this.Size = new Size(100, 100);

    }

    protected override void OnControlAdded(ControlEventArgs e)
    {
        for (int i = 0; i < Items.Length; i++)
        {
            if (i == 0)
                Items[i].Location = new Point(2 + Padding.Left, 2 + Padding.Top);
            else
                Items[i].Location = new Point(2 + Padding.Left, Items[i - 1].Location.Y + Size.Ceiling(this.CreateGraphics().MeasureString(Items[i - 1].Text, Items[i - 1].Font)).Height);
        }
        base.OnControlAdded(e);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        Graphics canvas = e.Graphics;
        canvas.SmoothingMode = SmoothingMode.HighQuality;
        Rectangle region = new Rectangle(0, 0, ClientRectangle.Width - 1, ClientRectangle.Height - 1);
        GraphicsPath path = Utilities.RoundedRectangle.Create(region, CornerRadius, Corners);
        canvas.FillPath(new LinearGradientBrush(region, fillColors[0], fillColors[1], 90), path);
        canvas.DrawPath(new Pen(borderColor), path);
    }
}

1 个答案:

答案 0 :(得分:0)

我明白了!我应该在OnControlAdded方法中设置它们,而不是在OnPaint方法中设置复选框的位置。此外,在OnScroll方法上,我需要使控件无效,导致它重绘。

所以,它应该(可能不是应该,但可能)看起来像这样:

public class ChromeCheckListBox : ChromeContainerControl
{
    [Description("Determines what corner(s) will be rounded.")]
    public Utilities.RoundedRectangle.RectangleCorners Corners { get; set; }

    private int cornerRadius;
    [Description("Determines the radius of the the corners")]
    public int CornerRadius
    {
        get { return cornerRadius; }
        set
        {
            if (value < 1)
                Utilities.ThrowError("The radius cannot be less than 1. If you want no radius, set Corners to None.");
            else
                cornerRadius = value;
        }
    }

    [Description("Determines the list of ChromeRadioButton controls that are displayed.")]
    private ChromeCheckBox[] items;
    public ChromeCheckBox[] Items
    {
        get { return items; }
        set
        {
            items = value;
            Controls.Clear();
            Controls.AddRange(items);
        }
    }

    public ChromeCheckListBox()
    {
        this.AutoScroll = true;
        this.Corners = Utilities.RoundedRectangle.RectangleCorners.All;
        this.CornerRadius = 1;
        this.Items = new ChromeCheckBox[0];
        this.Size = new Size(100, 100);

    }

    protected override void OnControlAdded(ControlEventArgs e)
    {
        for (int i = 0; i < Items.Length; i++)
        {
            if (i == 0)
                Items[i].Location = new Point(2 + Padding.Left, 2 + Padding.Top);
            else
                Items[i].Location = new Point(2 + Padding.Left, Items[i - 1].Location.Y + Size.Ceiling(this.CreateGraphics().MeasureString(Items[i - 1].Text, Items[i - 1].Font)).Height);
        }
        base.OnControlAdded(e);
    }

    protected override void OnScroll(ScrollEventArgs se)
    {
        base.OnScroll(se);
        base.Invalidate();
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        Graphics canvas = e.Graphics;
        canvas.SmoothingMode = SmoothingMode.AntiAlias;
        Rectangle region = new Rectangle(0, 0, ClientRectangle.Width - 1, ClientRectangle.Height - 1);
        GraphicsPath path = Utilities.RoundedRectangle.Create(region, CornerRadius, Corners);
        canvas.FillPath(new LinearGradientBrush(region, fillColors[0], fillColors[1], 90), path);
        canvas.DrawPath(new Pen(borderColor), path);
    }