'Textbox text disappears when transparency turned on and control loses focus

I have researched creating a custom winforms Textbox that allows a transparent background. I read the StackOverflow post:

Link to post.

In that post dkiefer asked about the problem that the text goes away after it is typed in the textbox. No one ever answered his question, and I'm stuck with this same problem. The text disappears, though it is still there when I go back in to edit it.

I can post the complete code, which is rather lengthy, but it is exact to the StackOverflow link noted above. Does anyone have an answer to this?



Solution 1:[1]

I had all sorts of problems trying to do something similar. My specific problem was that I was overlaying the transparent textbox on an image - this whole solution blows up when there is another control between the transparent textbox and the form background.

What I ended up doing (although it seems kind of hackish) is using both a transparent textbox and a label. I handled the Leave (lose focus) event on the textbox and the Click event on the label, and used these handlers to sync the text and toggle visibility of the controls. When you click the label, you magically have a nice transparent textbox that you can type in, and when it loses focus, you have a transparent label that works as expected. I don't have the source code handy, but I think I defined a user control that contained most of the logic so that it was straightforward to drop in and use as needed.

I'm sure there are better solutions (using WPF is my personal favorite "better solution", although my coworkers are tired of hearing it. lol)

Solution 2:[2]

Good evening, I understand that it's too late to answer this question, but today I suffered the same problem. And for me, as a beginner, it was difficult to find the answer (and the deadline for release was running out to start learning WPF). And this answer above, literally saved me. But there is no implementation in it, and I would just like to share with other newbies how I implemented it and how it worked for me.

To begin with, it is worth implementing the class, as indicated in the link: https://stackoverflow.com/a/16050862/18680342 When you create a class and start using the new Textbox, texts will disappear when defocused. This can be fixed as suggested in the answer above https://stackoverflow.com/a/41575889/18680342 To do this, you can specify events in the class itself.

this.MouseLeave += new EventHandler(CustomTextBox_MouseLeave);
        this.TextChanged += new EventHandler(CustomTextBox_MouseLeave);

as well as actions for them

public void CustomTextBox_MouseLeave(object sender, EventArgs e)
    {
        if (Text.Length > 0)
        {
            SetStyle(
                        ControlStyles.UserPaint,
                        false);
            BackColor = Color.White;
            ForeColor = Color.Gray;
        }
        else
        {
            SetStyle(ControlStyles.SupportsTransparentBackColor |
                      ControlStyles.OptimizedDoubleBuffer |
                      ControlStyles.AllPaintingInWmPaint |
                      ControlStyles.ResizeRedraw |
                      ControlStyles.UserPaint,
                      true);
            BackColor = Color.Transparent;
        }
    }

Thus, when pressed, a white background will appear (you can replace it with any color that is convenient and more suitable for the background, the main thing is that the alpha is 255). When deleting the text and when the TextBox is empty, transparency will return to us again.

This will be enough for someone, but in my program I needed it to be transparent and along with the text (at least in an inactive state). To do this, again, as suggested earlier, you can do this: We will create a label that is not initially visible, and when leaving the focus with the TextBox, we will make it visible, set the text to the same as the TextBox, and delete the text in the editable field. And of course, the Label should have the same font and background transparency, its parent will be the TextBox for stretching. Optionally, you can hang a Scroll on the TextBox itself. Here is the code for the complete implementation. If anyone knows a better method, I would be interested to know.

namespace textbox
{
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    Label lab1 = new Label();
    
    private void Form1_Load(object sender, EventArgs e)
    {
        Label lab = new Label();
        lab.Parent = customTextBox2; 
        lab.Size = customTextBox2.Size;
        lab.BackColor = Color.Transparent;
        lab.Visible = false;
        customTextBox2.WordWrap = true;
        //optionality
        //customTextBox2.BorderStyle = BorderStyle.None;
        lab.Click += new EventHandler(lab_Click);
        lab1 = lab;
    }

    private void customTextBox1_MouseHover(object sender, EventArgs e)
    {
        
    }

    private void customTextBox2_Leave(object sender, EventArgs e)
    {
        lab1.Text = customTextBox2.Text;
        lab1.Visible = true;
        customTextBox2.Text = "";
    }

    private void customTextBox2_Click(object sender, EventArgs e)
    {
        lab1.Visible = false;
        customTextBox2.Text = lab1.Text;
    }
    private void lab_Click(object sender, EventArgs e)
    {
        lab1.Visible = false;
        customTextBox2.Text = lab1.Text;
    }
}
public partial class CustomTextBox : TextBox
{
    public CustomTextBox()
    {

        //InitializeComponent();
         SetStyle(ControlStyles.SupportsTransparentBackColor |
                  ControlStyles.OptimizedDoubleBuffer |
                  ControlStyles.AllPaintingInWmPaint |
                  ControlStyles.ResizeRedraw |
                  ControlStyles.UserPaint, 
                  true);
        BackColor = Color.Transparent;
        this.MouseLeave += new EventHandler(CustomTextBox_MouseLeave);
        this.TextChanged += new EventHandler(CustomTextBox_MouseLeave);

    }
    public void CustomTextBox_MouseLeave(object sender, EventArgs e)
    {
        if (Text.Length > 0)
        {
            SetStyle(
                        ControlStyles.UserPaint,
                        false);
            BackColor = Color.White;
            ForeColor = Color.Gray;
        }
        else 
        {
            SetStyle(ControlStyles.SupportsTransparentBackColor |
                      ControlStyles.OptimizedDoubleBuffer |
                      ControlStyles.AllPaintingInWmPaint |
                      ControlStyles.ResizeRedraw |
                      ControlStyles.UserPaint,
                      true);
            BackColor = Color.Transparent;
        }
        
    }
}
}

For those who need to remove focus from a TextBox or any other control, you can implement the Form Click method and specify

this.ActiveControls = null;

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Dave Smash
Solution 2 Sherlock_201