自定义控件不能绘画?

时间:2019-01-02 18:53:06

标签: c# winforms onpaint

我创建了一个自定义控件来绘制一个Dial型仪表,但是遇到了一个奇怪的问题。我正在使用压力表的形式有两个这样的压力表。一个量规可以很好地工作(一个量规停在左侧),但即使在Visual Studio中,右侧的量规也无法显示。

如果我在Visual Studio中,并且从“代码”选项卡更改为带有量规的选项卡,则永远不会绘制一个量规,并且它仍显示上一个选项卡中的文本。如果我单击量规,则量规会突然绘制。

在程序也运行时会发生这种情况,而不是重新绘制空间,它只是完全透明的,甚至擦除了表单背景。

Paint Issue

OnPaint代码如下:

protected override void OnPaint(PaintEventArgs e)
{
    int size = ClientSize.Height - GaugeThickness;

    float x = (GaugeThickness / 2) + OffsetX;
    float y = (GaugeThickness / 2) + OffsetY;

    if (this.HorizontalAlignment == HorizontalAlignment.Left)
    {
        x = ((size / 2) * -1) + OffsetX;
    }
    else if (this.HorizontalAlignment == HorizontalAlignment.Right)
    {
        x = (size / 2) + OffsetX;
    }

    if (this.VerticalAlignment == VerticalAlignment.Top)
    {
        y = ((size / 2) * -1) + OffsetY;
    }
    else if (this.VerticalAlignment == VerticalAlignment.Bottom)
    {
        y = (size / 2) + OffsetY;
    }

    PaintBackground(e, x, y);
    PaintText(e, x, y, size, size);
    PaintMarks(e, x, y);
    PaintNeedle(e, x, y);
}

protected virtual void PaintBackground(PaintEventArgs e, float x, float y)
{
    int size = ClientSize.Height - GaugeThickness;
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;


    //Draw background
    using (Pen p = new Pen(GaugeColor, GaugeThickness))
    {
        e.Graphics.DrawArc(p, x, y, size, size, StartAngle, SweepAngle);
    }
}

protected virtual void PaintText(PaintEventArgs e, float x, float y, int width, int height)
{
    TextFormatFlags horizontal = TextFormatFlags.HorizontalCenter;
    TextFormatFlags vertical = TextFormatFlags.VerticalCenter;

    if (this.TextAlignmentHorizontal == HorizontalAlignment.Left)
    {
        horizontal = TextFormatFlags.Left;
    }
    else if (this.TextAlignmentHorizontal == HorizontalAlignment.Right)
    {
        horizontal = TextFormatFlags.Right;
    }

    if (this.TextAlignmentVertical == VerticalAlignment.Top)
    {
        vertical = TextFormatFlags.Top;
    }
    else if (this.TextAlignmentVertical == VerticalAlignment.Bottom)
    {
        vertical = TextFormatFlags.Bottom;
    }
    Rectangle rect = new Rectangle((int)x, (int)y, width, height);
    e.Graphics.FillEllipse(new SolidBrush(Color.Transparent), rect);
    TextRenderer.DrawText(e.Graphics, this.Text, this.Font, rect,
        this.ForeColor, horizontal | vertical);
}

protected virtual void PaintMarks(PaintEventArgs e, float x, float y)
{
    int size = ClientSize.Height - GaugeThickness;
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

    //Draw Marks
    float markLocation = 0.0f;
    float spacing = SweepAngle / 10;
    for (int i = 0; i < 11; i++)
    {
        using (Pen p = new Pen(MarkColor, MarkLength))
        {
            p.Alignment = PenAlignment.Inset;
            e.Graphics.DrawArc(p, x, y, size, size, markLocation + StartAngle, MarkThickness);
            markLocation += spacing;
        }
    }
}

protected virtual void PaintNeedle(PaintEventArgs e, float x, float y)
{
    int size = ClientSize.Height - GaugeThickness;
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

    //Draw needle.
    if (Value >= MaxValue) Value = MaxValue;
    using (Pen p = new Pen(NeedleColor, NeedleLength))
    {
        p.Alignment = PenAlignment.Inset;
        e.Graphics.DrawArc(p, x, y, size, size, StartAngle + GetNeedleAngle(), NeedleSweep);
    }
    base.OnPaint(e);
}

我真的不知道有什么线索导致整个控件在单击之前完全无法绘制。

我已经检查了Display.Designer.CS,并且两个控件都添加到了“ Display.Controls”中。

有人看到我不知道的东西吗?

我运行了Debug,实际上直到GPU标尺失去/获得焦点后,OnPaint函数才真正在GPU标尺上被调用。

这是我整个DialGauge课:

public class DialGauge : Control
{
    #region Properties
    [Browsable(true)]
    public float StartAngle { get => _startAngle; set { _startAngle = value; Invalidate(); } }

    [Browsable(true)]
    public float SweepAngle { get => _sweepAngle; set { _sweepAngle = value; Invalidate(); } }

    [Browsable(true)]
    [DefaultValue(100d)]
    public double MaxValue { get => _maxvalue; set { _maxvalue = value; Invalidate(); } }

    [Browsable(true)]
    public int GaugeThickness { get => _gaugethickness; set { _gaugethickness = value; Invalidate(); } }

    [Browsable(true)]
    [DefaultValue(150)]
    public int NeedleLength { get => _needlelength; set { _needlelength = value; Invalidate(); } }

    [Browsable(true)]
    [DefaultValue(5)]
    public float NeedleSweep { get => _needlesweep; set { _needlesweep = value; Invalidate(); } }

    [Browsable(true)]
    [DefaultValue(0.0)]
    public double Value { get => _value; set { _value = value; Invalidate(); } }

    [Browsable(true)]
    public Color GaugeColor { get => gaugecolor; set { gaugecolor = value; Invalidate(); } }

    [Browsable(true)]
    public Color NeedleColor { get => needlecolor; set { needlecolor = value; Invalidate(); } }

    [Browsable(true)]
    public float MarkLength { get => _marklength; set { _marklength = value; Invalidate(); } }

    [Browsable(true)]
    public Color MarkColor { get => _markcolor; set { _markcolor = value; Invalidate(); } }

    [Browsable(true)]
    public float MarkThickness { get => _markthickness; set { _markthickness = value; Invalidate(); } }

    [Browsable(true)]
    [DefaultValue(HorizontalAlignment.Center)]
    public HorizontalAlignment HorizontalAlignment { get => _horizontalalignment; set { _horizontalalignment = value; Invalidate(); } }

    [Browsable(true)]
    [DefaultValue(VerticalAlignment.Center)]
    public VerticalAlignment VerticalAlignment { get => _verticalalignment; set { _verticalalignment = value; Invalidate(); } }

    [Browsable(true)]
    [DefaultValue(0f)]
    public float OffsetX { get => _offset_x; set { _offset_x = value; Invalidate(); } }

    [Browsable(true)]
    [DefaultValue(0f)]
    public float OffsetY { get => _offset_y; set { _offset_y = value; Invalidate(); } }

    [Browsable(true)]
    [DefaultValue(HorizontalAlignment.Center)]
    public HorizontalAlignment TextAlignmentHorizontal { get => _texthorizontalalignment; set { _texthorizontalalignment = value; Invalidate(); } }

    [Browsable(true)]
    [DefaultValue(VerticalAlignment.Center)]
    public VerticalAlignment TextAlignmentVertical { get => _textverticalalignment; set { _textverticalalignment = value; Invalidate(); } }

    [Browsable(true)]
    public override string Text { get => base.Text; set { base.Text = value; Invalidate(); } }

    [Browsable(true)]
    public override Font Font { get => base.Font; set { base.Font = value; Invalidate(); } }

    protected float _startAngle;
    protected float _sweepAngle;
    protected double _maxvalue;
    protected int _gaugethickness;
    protected int _needlelength;
    protected float _needlesweep;
    protected double _value;
    protected Color gaugecolor;
    protected Color needlecolor;
    protected float _marklength;
    protected Color _markcolor;
    protected float _markthickness;
    protected HorizontalAlignment _horizontalalignment;
    protected VerticalAlignment _verticalalignment;
    protected HorizontalAlignment _texthorizontalalignment;
    protected VerticalAlignment _textverticalalignment;
    protected float _offset_x;
    protected float _offset_y;
    #endregion

    public DialGauge()
    {
        this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
        DoubleBuffered = true;
    }

    #region PAINT
    protected override void OnPaint(PaintEventArgs e)
    {
        int size = ClientSize.Height - GaugeThickness;

        float x = (GaugeThickness / 2) + OffsetX;
        float y = (GaugeThickness / 2) + OffsetY;

        if (this.HorizontalAlignment == HorizontalAlignment.Left)
        {
            x = ((size / 2) * -1) + OffsetX;
        }
        else if (this.HorizontalAlignment == HorizontalAlignment.Right)
        {
            x = (size / 2) + OffsetX;
        }

        if (this.VerticalAlignment == VerticalAlignment.Top)
        {
            y = ((size / 2) * -1) + OffsetY;
        }
        else if (this.VerticalAlignment == VerticalAlignment.Bottom)
        {
            y = (size / 2) + OffsetY;
        }

        PaintBackground(e, x, y);
        PaintText(e, x, y, size, size);
        PaintMarks(e, x, y);
        PaintNeedle(e, x, y);
    }

    protected virtual void PaintBackground(PaintEventArgs e, float x, float y)
    {
        int size = ClientSize.Height - GaugeThickness;
        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;


        //Draw background
        using (Pen p = new Pen(GaugeColor, GaugeThickness))
        {
            e.Graphics.DrawArc(p, x, y, size, size, StartAngle, SweepAngle);
        }
    }

    protected virtual void PaintText(PaintEventArgs e, float x, float y, int width, int height)
    {
        TextFormatFlags horizontal = TextFormatFlags.HorizontalCenter;
        TextFormatFlags vertical = TextFormatFlags.VerticalCenter;

        if (this.TextAlignmentHorizontal == HorizontalAlignment.Left)
        {
            horizontal = TextFormatFlags.Left;
        }
        else if (this.TextAlignmentHorizontal == HorizontalAlignment.Right)
        {
            horizontal = TextFormatFlags.Right;
        }

        if (this.TextAlignmentVertical == VerticalAlignment.Top)
        {
            vertical = TextFormatFlags.Top;
        }
        else if (this.TextAlignmentVertical == VerticalAlignment.Bottom)
        {
            vertical = TextFormatFlags.Bottom;
        }
        Rectangle rect = new Rectangle((int)x, (int)y, width, height);
        e.Graphics.FillEllipse(new SolidBrush(Color.Transparent), rect);
        TextRenderer.DrawText(e.Graphics, this.Text, this.Font, rect,
            this.ForeColor, horizontal | vertical);
    }

    protected virtual void PaintMarks(PaintEventArgs e, float x, float y)
    {
        int size = ClientSize.Height - GaugeThickness;
        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

        //Draw Marks
        float markLocation = 0.0f;
        float spacing = SweepAngle / 10;
        for (int i = 0; i < 11; i++)
        {
            using (Pen p = new Pen(MarkColor, MarkLength))
            {
                p.Alignment = PenAlignment.Inset;
                e.Graphics.DrawArc(p, x, y, size, size, markLocation + StartAngle, MarkThickness);
                markLocation += spacing;
            }
        }
    }

    protected virtual void PaintNeedle(PaintEventArgs e, float x, float y)
    {
        int size = ClientSize.Height - GaugeThickness;
        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

        //Draw needle.
        if (Value >= MaxValue) Value = MaxValue;
        using (Pen p = new Pen(NeedleColor, NeedleLength))
        {
            p.Alignment = PenAlignment.Inset;
            e.Graphics.DrawArc(p, x, y, size, size, StartAngle + GetNeedleAngle(), NeedleSweep);
        }
        base.OnPaint(e);
    }
    #endregion

    protected float GetNeedleAngle()
    {
        float percentage = (float)(Value / MaxValue);
        float angle = SweepAngle * percentage;

        return angle;
    }
}

0 个答案:

没有答案