WinFormsラベルが透明になりたくない理由は何ですか?
-
03-07-2019 - |
質問
ラベルのBackColorを透明に設定できないのはなぜですか?以前にやったことがありますが、今はしたくない...
新しいUserControlを作成し、プログレスバーとラベルを追加しました。ラベルのBackColorを透明に設定しても、灰色のままです= /なぜですか?
私が欲しかったのは、プログレスバーの上部にラベルを付けて、そのテキストが「イン」であるようにすることでした。プログレスバー...
解決
WinFormsは透明コントロールを実際にはサポートしていませんが、自分で透明コントロールを作成できます。 こちらから私の回答をご覧ください。
おそらく、プログレスバーをサブクラス化し、OnPaintメソッドをオーバーライドしてプログレスバーにテキストを描画する必要があります。
他のヒント
プロジェクトに新しいクラスを追加し、以下に示すコードを投稿します。ビルド。ツールボックスの上部からフォームに新しいコントロールをドロップします。
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;
}
}
}
最も簡単な解決策は次のとおりです。
-
ビジュアルエディターまたはフォームのコンストラクターのいずれかで背景色を透明に設定します。
this.label1.BackColor = System.Drawing.Color.Transparent;
-
ラベルのParentプロパティを設定して、テキストの背後に表示されるようにします。これは、フォームコンストラクターまたはLoadメソッドで実行できます。
this.label1.Parent = progressBar1;
これは、DirectXのように真の透明性ではないことは事実です。ディスプレイに表示される結果は、2つのレイヤーのみで構成されています。このアプローチでは、3つ以上のレイヤーを合計することはできません(各レイヤーは、alphaパラメーターで定義された独自の透明度を持ちます)。しかし、Winformsプログラミングで遭遇する可能性のある多くの実用的な状況に適しています。
通常のラベルではなく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;
}
Windowsアプリケーションの設計に集中したい場合は、WPFを使用することをお勧めします。
WPFでコントロールを透明にすることは非常に簡単です。
<TextBox Width="200" Height="40" Opacity="0.5"/>
これは、前に書いた透明なコントロールで、回転したテキストを表示します。コードの大部分はこちらから取得していますが、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);
}
}
}
これは非常にシンプルなソリューションであり、うまく機能します。
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);
}
}
ラベルの背景色が透明の場合、ラベルは、ラベルの背景色が一定になった後、最初に作成されたときのみ、基礎となるコントロールの写真を撮ります。そして、ラベルがそれ自体を再描画するたびに、その固定色またはパターンに再描画されます。
CreateParamsのオーバーライドは、コントロール用のウィンドウの作成方法に影響します。これにより、実際の透明度が有効になります。
WndProcをオーバーライドして、基本クラスに渡すメッセージを制御します。 WM_ERASEBKGNDとWM_PAINTをフィルタリングする必要がありますが、ペイントイベントをトリガーする必要もあります。
したがって、前の回答へのコメントが述べたように、Controlはデフォルトの動作であり、透明であると私が覚えていたものです。
とにかく、UserControlの背景プロパティ、またはラベルが入っているコンテナ(パネル、フォームなど)を設定しようとしましたが、ラベルはその色を反映する必要があります:)
旧回答: winformsプログラミングを行ってからしばらく経ちましたが、思い出すと、ラベルはデフォルトで透明になっていますか?したがって、実際の色を取得するテキストと暗色はその背後にあるものを模倣します:)
達成したいことを正確に行うことができます。コントロールを操作するには少し時間がかかります。背景が透明なLabelコントロールを作成し、Progressbarコントロールの上に配置することができます。
別のSO質問私の回答を確認してください。
あなたの問題の説明としては、ウィンドウはあなたが期待するような背景コントロールの透明性を行いません-私は灰色の背景が実際にフォームの表面であると推測しています。フォームサーフェスとラベルの間に描画されるコントロールはすべて無視されます。
BackColor を選択し、Webタブに移動して、透明を選択します。以下を生成します。
this.label1.BackColor = System.Drawing.Color.Transparent;