GPAL - Generally Positive Automation Library v1.0
GPAL The Fluent Automation LIbrary
Loading...
Searching...
No Matches
PlaceholderTextbox.cs
1// =============================================================================
2// GPAL - Generally Positive Automation Library
3// Copyright © 2026 Software Decisions, Inc. All rights reserved.
4//
5// This file is part of GPAL.
6// Licensed under the Business Source License 1.1
7//
8// Primary development, architecture, and vision by Michael B. Vederman,
9// CEO of Software Decisions, Inc., Texas.
10//
11// Internal development maintained privately.
12// Public releases appear on GitHub: https://github.com/SoftwareDecisionsInc/GPAL.
13//
14// See LICENSE for full terms, including Additional Use Grant.
15// =============================================================================
16
17using System;
18using System.Collections.Generic;
19using System.Drawing;
20using System.Linq;
21using System.Text;
22using System.Threading.Tasks;
23using System.Windows.Forms;
24
26{
30 public class PlaceholderTextBox : TextBox
31 {
32 private bool isPlaceholder = false;
33 private string placeholderText;
34
35 public string PlaceholderText
36 {
37 get { return placeholderText; }
38 set
39 {
40 placeholderText = value;
41 SetPlaceholder();
42 }
43 }
44
45 private bool _suppressPlaceholder = false;
46
47 public PlaceholderTextBox()
48 {
49 TextChanged += OnTextChanged;
50 }
51
52 protected override void OnGotFocus(EventArgs e)
53 {
54 base.OnGotFocus(e);
55
56 // clearing on focus is for placeholder text and nothing else, so what is on screen has to actually
57 // be the placeholder. Taking the flag's word for it is how real text gets wiped by a click
58 if (isPlaceholder && this.Text == placeholderText)
59 {
60 _suppressPlaceholder = true;
61 isPlaceholder = false;
62 this.ForeColor = System.Drawing.SystemColors.WindowText;
63 this.Text = "";
64 _suppressPlaceholder = false;
65 }
66 }
67
68 protected override void OnLostFocus(EventArgs e)
69 {
70 base.OnLostFocus(e);
71 if (!isPlaceholder && string.IsNullOrEmpty(this.Text))
72 SetPlaceholder();
73 }
74
75 private void SetPlaceholder()
76 {
77 // a box with no placeholder has nothing to show. Marking it as showing one anyway makes the next
78 // thing written into it look like placeholder text, and the next click wipes it: an empty box that
79 // loses focus was being flagged, and OnTextChanged returns early when there is no placeholder, so
80 // nothing ever cleared the flag again
81 if (!isPlaceholder && !string.IsNullOrEmpty(placeholderText))
82 {
83 this.Text = placeholderText;
84 this.ForeColor = Color.Gray;
85 isPlaceholder = true;
86 }
87 }
88
89 private void RemovePlaceHolder()
90 {
91 if (isPlaceholder)
92 {
93 this.ForeColor = System.Drawing.SystemColors.WindowText;
94 isPlaceholder = false;
95 }
96 }
97
98 private void OnTextChanged(object sender, EventArgs e)
99 {
100 if (_suppressPlaceholder || string.IsNullOrEmpty(placeholderText))
101 return;
102
103 if (this.Text.Length == 0 && !this.Focused)
104 SetPlaceholder();
105 else
106 RemovePlaceHolder();
107 }
108 }
109}
110