it-swarm.com.de

Gründe, warum ein WinForms-Label nicht transparent sein möchte?

Warum kann ich die Hintergrundfarbe eines Etiketts nicht auf Transparent setzen? Ich habe es schon einmal gemacht, aber jetzt will es einfach nicht ...

Ich habe ein neues UserControl erstellt, eine Fortschrittsanzeige und eine Beschriftung hinzugefügt. Wenn ich die Hintergrundfarbe des Etiketts auf transparent stelle, ist es immer noch grau =/Warum ist das so?

Was ich wollte, war, das Etikett oben auf der Fortschrittsleiste zu haben, so dass sein Text "in" der Fortschrittsleiste war ...

27
Svish

WinForms unterstützt keine transparenten Steuerelemente, Sie können jedoch selbst ein transparentes Steuerelement erstellen. Siehe meine Antwort hier .

In Ihrem Fall sollten Sie wahrscheinlich die Fortschrittsanzeige unterordnen und die OnPaint-Methode überschreiben, um einen Text in die Fortschrittsanzeige zu zeichnen.

14
Rune Grimstad

Fügen Sie Ihrem Projekt eine neue Klasse hinzu und veröffentlichen Sie den unten gezeigten Code. Bauen. Ziehen Sie das neue Steuerelement vom oberen Rand der Toolbox auf Ihr Formular.

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;
    }
  }
}
31
Hans Passant

Die einfachste Lösung ist folgende:

  1. Stellen Sie die Hintergrundfarbe entweder im visuellen Editor oder im Konstruktor Ihres Formulars auf Transparenz ein:

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

  2. Legen Sie die Parent-Eigenschaft Ihres Etiketts fest, um zu steuern, dass Sie hinter dem Text sichtbar sein möchten. Dies kann im Formularkonstruktor oder in der Load-Methode erfolgen:

    this.label1.Parent = progressBar1;

Es ist wahr, dass dies keine echte Transparenz wie in DirectX ist. Das angezeigte Ergebnis besteht nur aus zwei Ebenen. Sie können mit diesem Ansatz nicht mehr als zwei Ebenen zusammenfassen (jede Ebene hat ihre eigene Transparenz, die durch den Alpha-Parameter definiert wird). Aber es ist für viele praktische Situationen geeignet, die Sie in der Winforms-Programmierung finden können.

7
truthseeker

Verwenden Sie ein LinkLabel, kein normales Label

    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;
    }
4

Hier ist ein transparentes Steuerelement, das ich vor einiger Zeit geschrieben habe und das gedrehten Text anzeigt. Der größte Teil des Codes stammt von hier , obwohl ich im IIRC einige Anpassungen vornehmen musste, damit es funktioniert.

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);
        }
    }
}

Wenn Sie sich auf das Entwerfen Ihrer Windows-Anwendung konzentrieren möchten, empfehlen wir Ihnen, WPF zu verwenden.

Es ist sehr einfach, Steuerelemente in WPF transparent zu machen.

<TextBox Width="200" Height="40" Opacity="0.5"/>
1
はると

Dies ist eine sehr einfache Lösung und funktioniert hervorragend:

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);
    }
}

Wenn die Hintergrundfarbe des Etiketts transparent ist, nimmt das Etikett beim erstmaligen Erstellen nur ein Bild des zugrunde liegenden Steuerelements auf, nachdem die Hintergrundfarbe des Etiketts konstant ist. Und jedes Mal, wenn sich das Etikett neu einfärbt, wird es auf die festgelegte Farbe oder das festgelegte Muster neu eingefärbt.

Das Überschreiben von CreateParams wirkt sich darauf aus, wie das Fenster für die Steuerung erstellt wird. Dies ermöglicht echte Transparenz.

Durch Überschreiben von WndProc steuern Sie, welche Nachrichten an die Basisklasse übergeben werden sollen. Wir müssen WM_ERASEBKGND und WM_Paint filtern, aber wir müssen auch das Paint-Ereignis auslösen.

1

als Erklärung für Ihr Problem macht Windows keine Transparenz für Hintergrundsteuerelemente, wie Sie es erwarten würden - ich vermute, der graue Hintergrund ist tatsächlich die Oberfläche des Formulars. Alle Steuerelemente, die zwischen der Formularoberfläche und Ihrer Beschriftung gezeichnet werden, werden ignoriert.

0
lincolnk

Es ist möglich, genau das zu tun, was Sie erreichen möchten. Es dauert nur ein wenig, um mit den Steuerelementen zu spielen. Es ist möglich, ein Beschriftungssteuerelement mit transparentem Hintergrund zu erstellen und über dem Fortschrittsleistensteuerelement zu platzieren.

Überprüfen Sie meine Antwort auf eine andere SO Frage.

0
MaciekTalaska

Wie der Kommentar zu meiner vorherigen Antwort besagt, ist Steuerung das Standardverhalten und das, woran ich mich erinnerte, transparent zu sein.

Wie auch immer, haben Sie versucht, die Hintergrundeigenschaft Ihres UserControl festzulegen, oder den Container, in dem sich Ihre Beschriftung befindet (Bedienfeld, Formular, was auch immer?), Sollte Ihre Beschriftung diese Farbe widerspiegeln :)


Alte Antwort: Es ist schon eine Weile her, seit ich winforms programmiert habe, aber wie ich mich erinnere, sind Labels standardmäßig transparent? Daher ist es nur der Text, der eine tatsächliche Farbe erhält und die Hintergrundfarbe ahmt alles nach, was dahinter steckt :)

0
thmsn