C# Windows 窗体文本框的透明度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16050249/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Transparency for windows forms textbox
提问by P1C Unrelated
I'm using windows forms in C# and I need to make a textbox's background color transparent. I have a trackbar that goes from 0 to 255 that is supposed to control it, but I'm having some trouble. I created a question earlier today asking the exact same thing, but no success.
我在 C# 中使用 windows 窗体,我需要使文本框的背景颜色透明。我有一个从 0 到 255 的轨迹栏,应该可以控制它,但我遇到了一些麻烦。我今天早些时候创建了一个问题,询问完全相同的事情,但没有成功。
Here is the code I currently have:
这是我目前拥有的代码:
private void trackAlpha_ValueChanged(object sender, EventArgs e)
{
newColor = Color.FromArgb(trackAlpha.Value, colorDialog.Color.R, colorDialog.Color.G, colorDialog.Color.B);
colorDialog.Color = newColor; // The Windows dialog used to pick the colors
colorPreview.BackColor = newColor; // Textbox that I'm setting the background color
}
The problem is that absolutely nothing happens. Any ideas on why this is not working?
问题是绝对没有任何事情发生。关于为什么这不起作用的任何想法?
On the previous question, this nice guy said something about SetStyle(ControlStyles.SupportsTransparentBackColor, true);, but I have no idea on where I should put this.
在上一个问题上,这个好人说了一些关于SetStyle(ControlStyles.SupportsTransparentBackColor, true);,但我不知道我应该把它放在哪里。
采纳答案by Patrick D'Souza
You need to try out something like this.
你需要尝试这样的事情。
Add a new user control , say CustomTextBoxand change
添加一个新的用户控件,比如CustomTextBox并更改
public partial class CustomTextBox : UserControl
to
到
public partial class CustomTextBox : TextBox
You will then get the following error saying that the 'AutoScaleMode' is not defined. Delete the following line in the Designer.cs class.
然后您将收到以下错误,指出未定义“AutoScaleMode”。删除 Designer.cs 类中的以下行。
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
Make changes to the constructor of your newly added control as follows.
对新添加的控件的构造函数进行如下更改。
public partial class CustomTextBox : TextBox
{
public CustomTextBox()
{
InitializeComponent();
SetStyle(ControlStyles.SupportsTransparentBackColor |
ControlStyles.OptimizedDoubleBuffer |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.ResizeRedraw |
ControlStyles.UserPaint, true);
BackColor = Color.Transparent;
}
}
Build, close the custom control designer if open and you will be able to use this control on any other control or form.
构建、关闭自定义控件设计器(如果打开),您将能够在任何其他控件或窗体上使用此控件。
回答by madbrendon
Create a new control which inherits from TextBox, set the style to allow tranparency in the constructor. Then use your new control instead of TextBox
创建一个继承自 TextBox 的新控件,在构造函数中设置样式以允许透明。然后使用您的新控件而不是 TextBox
Do this in your constructor:
在您的构造函数中执行此操作:
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
This will allow your new control to have a transparent background color.
这将使您的新控件具有透明的背景颜色。
You can read more about control styles here; MSDN: Control Styles, this may help as well; Inheriting from a Windows Forms Control with Visual C#
您可以在此处阅读有关控件样式的更多信息;MSDN:控制样式,这也可能有帮助;使用 Visual C# 从 Windows 窗体控件继承
回答by Plater
I never liked having to make my own inherited controls for this. So I made a wrapper function to the private SetStyle function.
我从不喜欢为此制作我自己的继承控件。所以我对私有的 SetStyle 函数做了一个包装函数。
Try using it instead of creating your own class?
尝试使用它而不是创建自己的类?
public static bool SetStyle(Control c, ControlStyles Style, bool value)
{
bool retval = false;
Type typeTB = typeof(Control);
System.Reflection.MethodInfo misSetStyle = typeTB.GetMethod("SetStyle", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (misSetStyle != null && c != null) { misSetStyle.Invoke(c, new object[] { Style, value }); retval = true; }
return retval;
}
bool itWorked = SetStyle(myControl, ControlStyles.SupportsTransparentBackColor, true);
bool itWorked = SetStyle(myControl, ControlStyles.SupportsTransparentBackColor, true);
回答by Chicken
Sorry to uncover old posts, however, been searching for a few days now to find a solution to this awful problem of no transparency for textboxes!!! (Amazingly MSAccess has a check state to show transparency!)
很抱歉发现旧帖子,但是,现在已经搜索了几天,以找到解决文本框不透明的可怕问题的解决方案!!!(令人惊讶的是 MSAccess 有一个检查状态来显示透明度!)
Anyways, I have built a VB workaround, however, it is very crude and whilst may help a lot of people would also like any input from the more hard-core'rs with any insights...
无论如何,我已经构建了一个 VB 解决方法,但是,它非常粗糙,虽然可能会帮助很多人,但也希望来自更铁杆的任何意见和见解......
It basically uses the textbox, then sizes it away and replaces with a label (hence now representing a transparent "appearing" textbox. Also couple of other things like stopping the beeping if press enter on a single line textbox.
它基本上使用文本框,然后将其调整大小并替换为标签(因此现在代表一个透明的“出现”文本框。还有其他一些事情,例如如果在单行文本框上按 Enter 则停止发出哔哔声。
To use - Create a new class and paste ALL the code over the top this should create two custom objects ( CTextBox and CLabel ) - you only need to use CTEXTBOX in your form design.
要使用 - 创建一个新类并将所有代码粘贴到顶部,这应该创建两个自定义对象( CTextBox 和 CLabel ) - 您只需要在表单设计中使用 CTextBox 。
Easily converts into C, if that's your language, but please let me know if have any suggestions?
轻松转换为 C,如果那是您的语言,但如果有任何建议,请告诉我?
Imports System.ComponentModel
Public Class CTextBox
Inherits TextBox
Dim _zUseEnterAsTab As Boolean = True
Dim _zUseTransparent As Boolean = False
Dim _zUseTransparentColor As Color = Color.Transparent
Dim _zUseTransparentBorderColor As Color = Color.Gray
<Description("Use the Enter Key as Tab (Stops Beeps) only for Single line TextBox"), Category("CTextBox")> _
Public Property zUseEnterAsTab() As Boolean
Get
Return _zUseEnterAsTab
End Get
Set(value As Boolean)
_zUseEnterAsTab = value
Me.Invalidate()
End Set
End Property
<Description("Use Transparent TextBox"), Category("CTextBox")> _
Public Property zUseTransparent() As Boolean
Get
Return _zUseTransparent
End Get
Set(value As Boolean)
_zUseTransparent = value
Me.Invalidate()
End Set
End Property
<Description("Change the transparency to ANY color or shade or Alpha"), Category("CTextBox")> _
Public Property zUseTransparentColor() As Color
Get
Return _zUseTransparentColor
End Get
Set(value As Color)
_zUseTransparentColor = value
Me.Invalidate()
End Set
End Property
<Description("Border color of the texbox when transparency used"), Category("CTextBox")> _
Public Property zUseTransparentBorderColor() As Color
Get
Return _zUseTransparentBorderColor
End Get
Set(value As Color)
_zUseTransparentBorderColor = value
Me.Invalidate()
End Set
End Property
Protected Overrides Sub OnCreateControl()
'Again for my benifit - there may be other ways to force the transparency
'code at form / event startup, but this is the way i chose, any advice
'or alternatives would be great!! :)
If Not DesignMode Then
'Basically don't do in design mode!
If _zUseTransparent Then
'Added to handle the event of textbox dissabled
If Me.Enabled Then
CreateMyLabel(Me)
MakeLabelVisible(foundLabel, Me)
End If
End If
End If
MyBase.OnCreateControl()
End Sub
Protected Overrides Sub OnKeyPress(e As KeyPressEventArgs)
If MyBase.Multiline = True Then
MyBase.OnKeyPress(e)
Else
If e.KeyChar = Chr(Keys.Enter) Then
e.Handled = True
If zUseEnterAsTab = True Then SendKeys.Send("{tab}")
MyBase.OnKeyPress(e)
End If
End If
End Sub
Protected Overrides Sub OnLeave(e As EventArgs)
If _zUseTransparent Then
CreateMyLabel(Me)
MakeLabelVisible(foundLabel, Me)
End If
MyBase.OnLeave(e)
End Sub
Protected Overrides Sub OnEnter(e As EventArgs)
If _zUseTransparent Then
CreateMyLabel(Me)
MakeTextBoxVisible(foundLabel, Me)
End If
MyBase.OnEnter(e)
End Sub
Dim foundLabel As CLabel = Nothing
Sub CreateMyLabel(_TxtBox As CTextBox)
foundLabel = Nothing
Dim l As CLabel
If GetMyLabel("L_" & Me.Name, Me) Then
l = foundLabel
If Not l.Name = "L_" & Me.Name Then
MsgBox("L_" & Me.Name)
End If
l.Font = _TxtBox.Font
l.Text = _TxtBox.Text
l.BorderColor = _zUseTransparentBorderColor
l.BackColor = _zUseTransparentColor
l.BorderStyle = Windows.Forms.BorderStyle.None 'Handled by paint event
Else
l = New CLabel
l.Name = "L_" & _TxtBox.Name
l.BorderColor = _zUseTransparentBorderColor
l.BackColor = _zUseTransparentColor
l.Size = _TxtBox.Size
l.BorderStyle = Windows.Forms.BorderStyle.None 'Handled by paint event
l.AutoSize = False
l.Font = _TxtBox.Font
l.Location = _TxtBox.Location
l.Text = _TxtBox.Text
l.Anchor = _TxtBox.Anchor
_TxtBox.Parent.Controls.Add(l)
foundLabel = l
End If
End Sub
Function GetMyLabel(_LabelName As String, _TxtBox As CTextBox) As Boolean
For Each ctl As Control In _TxtBox.Parent.Controls
If ctl.Name = _LabelName Then
foundLabel = ctl
Return True
End If
Next
Return False
End Function
Private Sub MakeLabelVisible(_Label As CLabel, _TxtBox As CTextBox)
_Label.Location = _TxtBox.Location
_Label.Anchor = _TxtBox.Anchor
_Label.Size = _TxtBox.Size
_TxtBox.Size = New Size(0, 0)
_TxtBox.Anchor = AnchorStyles.None
End Sub
Private Sub MakeTextBoxVisible(_Label As CLabel, _TxtBox As CTextBox)
_TxtBox.Location = _Label.Location
_TxtBox.Anchor = _Label.Anchor
_TxtBox.Size = _Label.Size
_Label.Size = New Size(0, 0)
_Label.Anchor = AnchorStyles.None
End Sub
End Class
Public Class CLabel
Inherits Label
Public BorderColor As Color = Color.Gray
Sub New()
MyBase.FlatStyle = Windows.Forms.FlatStyle.Standard
'Added padding as labels shifted text upwards
'NOT tested on all fonts etc, purely for my sources
MyBase.Padding = New Padding(0, 3, 0, 0)
End Sub
Protected Overrides Sub OnMouseDown(e As MouseEventArgs)
Dim _TxtBox As CTextBox = Nothing
Dim _TxtBoxName As String = Microsoft.VisualBasic.Right(Me.Name, Len(Me.Name) - 2)
For Each elem As Control In Me.Parent.Controls
If elem.Name = _TxtBoxName Then
_TxtBox = elem
Exit For
End If
Next
_TxtBox.Select()
MyBase.OnMouseDown(e)
End Sub
Protected Overrides Sub OnMouseEnter(e As EventArgs)
Cursor = Cursors.IBeam
MyBase.OnMouseEnter(e)
End Sub
Protected Overrides Sub OnMouseLeave(e As EventArgs)
Cursor = Cursors.Default
MyBase.OnMouseLeave(e)
End Sub
Protected Overrides Sub OnPaint(e As PaintEventArgs)
MyBase.OnPaint(e)
ControlPaint.DrawBorder(e.Graphics, Me.DisplayRectangle, Color.Gray, ButtonBorderStyle.Solid)
End Sub
Private Sub MakeLabelVisible(_Label As CLabel, _TxtBox As CTextBox)
_Label.Size = _TxtBox.Size
_TxtBox.Size = New Size(0, 0)
_Label.Anchor = _TxtBox.Anchor
_TxtBox.Anchor = AnchorStyles.None
End Sub
Private Sub MakeTextBoxVisible(_Label As CLabel, _TxtBox As CTextBox)
_TxtBox.Size = _Label.Size
_Label.Size = New Size(0, 0)
_TxtBox.Anchor = _Label.Anchor
_TxtBox.Anchor = AnchorStyles.None
End Sub
End Class
回答by user5666859
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
回答by Andy3D
The fact that this post is 6 years 7 months old, goes to tell that this issue is still out there, for I stumbled over this thread.
这篇文章已经有 6 年零 7 个月了,这一事实说明这个问题仍然存在,因为我偶然发现了这个线程。
Unfortunately I went ahead and implemented this for not only textbox (I derived from TextBox as described by Patrick D'Souza above) but figured it may work for Label equally well. The result was that the text box was not transparent, some of them defaulted back to system font but were visible only when being edited. The labels were not only transparent but invisible, including the text in the label. Sorry - not working. (Using 4.6 Client platform, and should have read beyond the first response!)
不幸的是,我继续并不仅为文本框实现了这个(我从上面的 Patrick D'Souza 描述的 TextBox 派生出来),而且认为它可能同样适用于 Label。结果是文本框不透明,有的默认回系统字体,但只有在编辑时才可见。标签不仅透明而且不可见,包括标签中的文字。对不起 - 不工作。(使用 4.6 客户端平台,应该已经阅读了第一个响应!)


