-1

I'm trying to create a simple textbox that shows a hint text when it's not focused and its text is empty, and hides the hint text when it's focused. To do that, I created a Custom Control by extending TextBox.

public partial class HintedTextBox : TextBox
{
    private Color foreColor;

    public HintedTextBox()
    {
        InitializeComponent();
        foreColor = ForeColor;
        GotFocus += OnFocused;
        LostFocus += OnFocusLost;

        OnFocusLost(null, null); // Problem
    }

    public string Hint { get; set; }

    protected override void OnPaint(PaintEventArgs pe)
    {
        base.OnPaint(pe);
    }

    private void OnFocused(object sender, EventArgs e)
    {
        if (Text == Hint)
        {
            Text = "";
            ForeColor = foreColor;
        }
    }

    private void OnFocusLost(object sender, EventArgs e)
    {
        if (Text.Trim() == "") 
        {
            Text = Hint;
            ForeColor = Color.Gray;
        }
        else
        {
            ForeColor = foreColor;
        }
    }
}

Logically, I would need to call the OnFocusLost() procedure after the component is initialized so the app will show the hint when the Form is first shown. The problem is at the line I marked with // problem. At this line, both my custom attribute Hint and the stock attribute Text are both not initialized, even if I've set their values in the Designer. The weird thing is that the ForeColor attribute is already initialized at that line. Is there another Event that fires as soon as these values are initialized, or is there any other solution?

I've also tried calling OnFocusLost() from outside the Control on Windows Form's FormLoad Event. It doesn't work either. The Text and Hint are just always empty at the start, even after the InitializeComponent() call.

Thank you for your attention.

EDIT: I forgot to attach the Form's on-load Event to my FormLoad() method, but nonetheless Vladimir Stoyanov's solution worked perfectly and even better.

adrilz
  • 785
  • 1
  • 5
  • 10
  • Define "initialized". Those properties are definitely initialized, as that's a basic C# feature. They may only be initialized to their default values though. If you are expecting them to be initialized to some other value, that would typically be handled in the `InitializeComponent()` method _for the containing object_, i.e. a `Form` subclass. Naturally, that code cannot have executed yet here, since the constructor hasn't returned yet. If you want an event to be raised when `Hint` is set, it's up to you to implement that. ... – Peter Duniho Aug 29 '20 at 02:44
  • ... There is already a `TextChanged` event for the `Text` property you inherited. You didn't post any `InitializeComponent()` method at all, never mind any of the code where one would expect these properties to be initialized, so it's impossible for anyone to answer your question correctly. Please see [mcve] and [ask]. – Peter Duniho Aug 29 '20 at 02:47
  • sounds like you want a watermark for the textbox? https://stackoverflow.com/questions/18497130/watermark-for-textbox/18497365 – traveler3468 Aug 29 '20 at 02:56
  • @PeterDuniho "Initialized" as in, if I've set the Hint attribute, let's say "Search", from the Designer, it should have the value "Search" after the InitializeComponent(), but it's null. The Text, even if I've set its value from the Designer, still remains "" in the constructor after the InitializeComponent(). – adrilz Aug 29 '20 at 03:01
  • @PeterDuniho Why do I need to post the contents of the InitializeComponent()? It's automatically generated by the Visual Studio. Am I supposed to post another 100 line? – adrilz Aug 29 '20 at 03:03

1 Answers1

0

As an option you can just use setter of the Hint property. It will handle the cases when you need to change your Hint programmatically later

private string hint;
public string Hint
{
    get => hint;
    set
    {
        hint = value;
        OnFocusLost(null, null);
    }
}