Подтвердить что ты не робот

Причины того, почему лейбл WinForms не хочет быть прозрачным?

Почему я не могу установить BackColor Label на Transparent? Я сделал это раньше, но теперь он просто не хочет...

Я создал новый UserControl, добавил к нему индикатор прогресса и ярлык. Когда я устанавливаю BackColor метки на прозрачный, он по-прежнему остается серым =/Почему это?

То, что я хотел, было иметь ярлык над панелью progress, чтобы его текст был "в" панели прогресса...

4b9b3361

Ответ 1

WinForms на самом деле не поддерживает прозрачные элементы управления, но вы можете сделать прозрачный контроль самостоятельно. См. мой ответ здесь.

В вашем случае вы, вероятно, должны подклассировать индикатор выполнения и переопределить метод OnPaint, чтобы нарисовать текст на панели выполнения.

Ответ 2

Добавьте новый класс в свой проект и опубликуйте код, показанный ниже. Построить. Отбросьте новый элемент управления сверху панели инструментов на форму.

using System;
using System.Windows.Forms;

public class TransparentLabel : Label {
  public TransparentLabel() {
    this.SetStyle(ControlStyles.Opaque, true);
    this.SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
  }
  protected override CreateParams CreateParams {
    get {
      CreateParams parms = base.CreateParams;
      parms.ExStyle |= 0x20;  // Turn on WS_EX_TRANSPARENT
      return parms;
    }
  }
}

Ответ 3

Самое простое решение:

  • Установите цвет фона для прозрачности в визуальном редакторе или в конструкторе вашей формы:

    this.label1.BackColor = System.Drawing.Color.Transparent;

  • Установите свойство Parent вашего ярлыка, чтобы контролировать, что вы хотите быть видимым за текстом. Это можно сделать в конструкторе форм или в методе загрузки:

    this.label1.Parent = progressBar1;

Это правда, что это не настоящая прозрачность, как в DirectX. Результат, который вы видите на дисплее, состоит только из двух слоев. Вы не можете подытожить более двух уровней с этим подходом (каждый слой имеет свою собственную прозрачность, определяемую альфа-параметром). Но это подходит для многих практических ситуаций, с которыми вы можете столкнуться в программировании Winforms.

Ответ 4

Используйте LinkLabel, а не нормальную метку

    private void MakeTransparentLabel(System.Windows.Forms.LinkLabel LinkLabel)
    {
        this.MakeTransparentLabel(LinkLabel, Color.White);
    }
    private void MakeTransparentLabel(System.Windows.Forms.LinkLabel LinkLabel, Color ForeColor)
    {
        LinkLabel.ForeColor = ForeColor;
        LinkLabel.LinkColor = ForeColor;
        LinkLabel.VisitedLinkColor = ForeColor;
        LinkLabel.ActiveLinkColor = ForeColor;
        LinkLabel.DisabledLinkColor = ForeColor;
        LinkLabel.LinkArea = new LinkArea(0, 0);
        LinkLabel.LinkBehavior = LinkBehavior.NeverUnderline;
        LinkLabel.Cursor = Cursors.Arrow;
        LinkLabel.BackColor = Color.Transparent;
    }
    private void SetTransparentLabelText(System.Windows.Forms.LinkLabel LinkLabel, string Text)
    {
        if (string.IsNullOrEmpty(Text)) { LinkLabel.Text = " "; return; }
        LinkLabel.Text = Text;
    }

Ответ 5

Если вы хотите сосредоточиться на разработке своего приложения Windows, я предлагаю вам использовать WPF.

Выполнение прозрачных преобразований в WPF очень просто.

<TextBox Width="200" Height="40" Opacity="0.5"/>

Ответ 6

Вот прозрачный элемент управления, который я написал некоторое время назад, который отображает повернутый текст. Большая часть кода происходит от здесь, хотя IIRC мне пришлось сделать несколько настроек, чтобы заставить его работать.

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Linq;
using System.Windows.Forms;

namespace MyNamespace
{
    public partial class RotatedText : UserControl
    {
        private readonly Timer _invalidationTimer;
        private const int WS_EX_TRANSPARENT = 0x00000020;

        public RotatedText()
        {
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            InitializeComponent();

            _invalidationTimer = new Timer {Interval = 500, Enabled = true};
            _invalidationTimer.Tick += TickHandler;
        }

        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [Category("Appearance")]
        [Description("Text which appears in control")]
        public string Text { get; set; }

        #region Transparent background
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= WS_EX_TRANSPARENT;
                return cp;
            }
        }

        private void TickHandler(object sender, EventArgs e)
        {
            InvalidateEx();
        }

        private void InvalidateEx()
        {
            if (Parent != null)
                Parent.Invalidate(Bounds, false);
            else
                Invalidate();
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
            //Intentionally do nothing - stops background from drawing
            //base.OnPaintBackground(e);
        } 
        #endregion

        //Rotate text and draw
        protected override void OnPaint(PaintEventArgs e)
        {
            double angleRadians = Math.Atan2(Height, Width);
            float angleDegrees = -1*(float) (angleRadians*180/Math.PI);
            angleDegrees *= 0.9f;
            e.Graphics.RotateTransform(angleDegrees, MatrixOrder.Append);
            e.Graphics.TranslateTransform(20, Height - 75, MatrixOrder.Append);
            e.Graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
            Font font = new Font("Ariel", 50);
            e.Graphics.DrawString(Text, font, Brushes.Gray, 1, 2); //Shadow
            e.Graphics.DrawString(Text, font, Brushes.Red, 0, 0);
        }
    }
}

Ответ 7

Это очень простое решение и отлично работает:

public class MyLabel : Label
{
    private bool fTransparent = false;
    public bool Transparent
    {
        get { return fTransparent; }
        set { fTransparent = value; }
    }
    public MyLabel() : base()
    {
    }
    protected override CreateParams CreateParams
    {
        get
        {
            if (fTransparent)
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x00000020; //WS_EX_TRANSPARENT
                return cp;
            }
            else return base.CreateParams;
        }
    }
    protected override void WndProc(ref Message m)
    {
        if (fTransparent)
        {
            if (m.Msg != 0x14 /*WM_ERASEBKGND*/ && m.Msg != 0x0F /*WM_PAINT*/)
                base.WndProc(ref m);
            else 
            {
                if (m.Msg == 0x0F) // WM_PAINT
                    base.OnPaint(new PaintEventArgs(Graphics.FromHwnd(Handle), ClientRectangle));
                DefWndProc(ref m);
            }
        }
        else base.WndProc(ref m);
    }
}

Если ярлык backcolor прозрачен, тогда метка берет только изображение его базового элемента управления в первый раз, когда он создается, после того, как эталонная обратная сторона является постоянной. И каждый раз, когда ярлык реплицируется сам, он перерисовывается на тот фиксированный цвет или узор.

Переопределение CreateParams влияет на то, как будет создаваться окно для управления, это обеспечивает реальную прозрачность.

Переопределяя WndProc, вы определяете, какие сообщения должны быть переданы базовому классу. Мы должны фильтровать WM_ERASEBKGND и WM_PAINT, но мы также должны вызвать событие рисования.

Ответ 8

Итак, как заметил комментарий к моему предыдущему ответу, Control - это поведение по умолчанию, и именно это я помню как прозрачный.

В любом случае, попробовали ли вы установить свойство фона вашего UserControl или контейнера, на котором находится ваш ярлык (Panel, Form, что?), ваш ярлык должен отражать этот цвет:)


Старый ответ: Это было некоторое время с тех пор, как я сделал winforms программирование, но, как я помню, метки прозрачны по умолчанию? таким образом, его единственный текст, который получает фактический цвет, и цвет фона, который имитирует все, что стоит за ним:)

Ответ 9

Можно сделать именно то, чего вы хотите достичь. Для управления требуется только немного времени. Можно создать элемент управления Label с прозрачным фоном и поместить его поверх элемента управления Progressbar.

Отметьте мой ответ на другой вопрос SO.

Ответ 10

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

Ответ 11

Выберите BackColor, перейдите на вкладку "Веб" и выберите "Прозрачный". Создает следующее.

        this.label1.BackColor = System.Drawing.Color.Transparent;