Прозрачные элементы управления на окрашенной форме - PullRequest
3 голосов
/ 09 июня 2011

Использование C # WinForms У меня есть форма, на которой я рисую градиентный фон от светло-синего до темно-синего. У меня есть несколько кнопок и несколько ярлыков, которые Я уже пытался установить прозрачный фоновый цвет , так как я хочу, чтобы фон просвечивал - особенно для ярлыков, но это не похоже на работу.

Но я заметил, что картина также рисует надписи, хотя код присутствует только в событии form_paint.

Как сделать так, чтобы этикетки не содержали одинаковую штриховку, но были прозрачными? например метки вверху формы будут светло-голубыми, а метки внизу - темно-синими.

private void frmOptions_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    Rectangle rectangle = e.ClipRectangle;

    using (Brush aBrush = new LinearGradientBrush(rectangle, Color.LightBlue, Color.DarkBlue, LinearGradientMode.Vertical))
    {
        e.Graphics.FillRectangle(aBrush, rectangle);
    }
}

Большое спасибо за любую помощь в этом.

EDIT: Я только что прошел по строкам кода для его отладки и заметил, что событие рисования вызывается для КАЖДОГО объекта в форме - меток и кнопок, прямоугольник в строке 2 выше имеет размер каждый раз. Так что теперь я действительно сбит с толку, почему он вызывается для каждого объекта в форме.

РЕДАКТИРОВАТЬ 2: Просто проходил код моего проекта быстрого тестирования (см. Комментарий ниже), а также заметил, что событие рисования вызывается для каждого объекта. Разница заключается в том, что в тестовом проекте нет строки "Rectangle rectangle = e.ClipRectangle;" - он в основном использует ширину и высоту формы. где мой код выше устанавливает прямоугольник в ClipRectangle - размер каждой метки и кнопки ... Это нормальное поведение? Если это так, то мне кажется, что мне нужно ответить на следующий ответ Рениуза.

РЕДАКТИРОВАТЬ 3 Я изменил строку cliprectangle на "Rectangle rectangle = new Rectangle(0, 0, this.Width, this.Height);". Это, кажется, делает прозрачный вид, как и должно, но событие рисования все еще вызывается для каждого объекта в форме - хорошая работа, есть только 7 из, так что это рисую 8 раз :( Думаю, я еще посмотрю на код "TransparentLabel", чтобы проверить это.

1 Ответ

4 голосов
/ 09 июня 2011

Взгляните на эту статью.

Редактировать:

Также вы можете использовать этот код:

public class TransparentLabel : Control
{
    public TransparentLabel(Label label)
    {
        //setting default properties
        this.Text = label.Text;
        this.Font = label.Font;
        this.Location = label.Location;
        this.Size = label.Size;
        this.Parent = label.Parent;
        this.BringToFront();
        label.Dispose();

        TabStop = false;
    }

    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ExStyle |= 0x20;
            return cp;
        }
    }

    protected override void OnPaintBackground(PaintEventArgs e)
    {
        // do nothing
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        DrawText();
    }

    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);
        if(m.Msg == 0x000F)
        {
            DrawText();
        }
    }

    private void DrawText()
    {
        using(Graphics graphics = CreateGraphics())
        using(SolidBrush brush = new SolidBrush(ForeColor))
        {
            SizeF size = graphics.MeasureString(Text, Font);

            // first figure out the top
            float top = 0;
            switch(textAlign)
            {
                case ContentAlignment.MiddleLeft:
                case ContentAlignment.MiddleCenter:
                case ContentAlignment.MiddleRight:
                    top = (Height - size.Height) / 2;
                    break;
                case ContentAlignment.BottomLeft:
                case ContentAlignment.BottomCenter:
                case ContentAlignment.BottomRight:
                    top = Height - size.Height;
                    break;
            }

            float left = -1;
            switch(textAlign)
            {
                case ContentAlignment.TopLeft:
                case ContentAlignment.MiddleLeft:
                case ContentAlignment.BottomLeft:
                    if(RightToLeft == RightToLeft.Yes)
                        left = Width - size.Width;
                    else
                        left = -1;
                    break;
                case ContentAlignment.TopCenter:
                case ContentAlignment.MiddleCenter:
                case ContentAlignment.BottomCenter:
                    left = (Width - size.Width) / 2;
                    break;
                case ContentAlignment.TopRight:
                case ContentAlignment.MiddleRight:
                case ContentAlignment.BottomRight:
                    if(RightToLeft == RightToLeft.Yes)
                        left = -1;
                    else
                        left = Width - size.Width;
                    break;
            }
            graphics.DrawString(Text, Font, brush, left, top);
        }
    }

    public override string Text
    {
        get
        {
            return base.Text;
        }
        set
        {
            base.Text = value;
            RecreateHandle();
        }
    }

    public override RightToLeft RightToLeft
    {
        get
        {
            return base.RightToLeft;
        }
        set
        {
            base.RightToLeft = value;
            RecreateHandle();
        }
    }

    public override Font Font
    {
        get
        {
            return base.Font;
        }
        set
        {
            base.Font = value;
            RecreateHandle();
        }
    }

    private ContentAlignment textAlign = ContentAlignment.TopLeft;
    public ContentAlignment TextAlign
    {
        get { return textAlign; }
        set
        {
            textAlign = value;
            RecreateHandle();
        }
    }
}

Прозрачная этикетка заменитсуществующий ярлык, чтобы вы могли использовать его следующим образом:

TransparentLabel transparentLabel1 = new TransparentLabel(label1);
TransparentLabel transparentLabel2 = new TransparentLabel(label2);

, а затем вы должны увидеть результат (время разработки слева, время выполнения справа):

labels

...