I'm trying to mimic the web functionality of having a label over a textbox that shows the type of value the textbox should contain. I can add the events individually but I'm wondering if there is a way to add 'Behavior' to a set of controls.
Please see example code:
private void labelFirstName_Click(object sender, EventArgs e)
{
HideLabelFocusTextBox(labelFirstName, textBoxFirstName);
}
private void HideLabelFocusTextBox(Label LabelToHide, TextBox TextBoxToShow)
{
LabelToHide.Visible = false;
TextBoxToShow.Focus();
}
private void textBoxFirstName_Leave(object sender, EventArgs e)
{
if (String.IsNullOrEmpty(textBoxFirstName.Text))
labelFirstName.Visible = true;
}
private void textBoxFirstName_Enter(object sender, EventArgs e)
{
labelFirstName.Visible = false;
}
You could subclass the text box control (write your own that inherits a textbox)
Btw, i have thought about this and i would take another approach:
i would override the text box's paint handler and when the textbox contains no information, draw an info string into it.
Something like:
using System;
using System.Windows.Forms;
using System.Drawing;
class MyTextBox : TextBox
{
public MyTextBox()
{
SetStyle(ControlStyles.UserPaint, true);
}
protected override void OnPaint(PaintEventArgs e)
{
if (string.IsNullOrEmpty(this.Text))
{
e.Graphics.DrawString("My info string...", this.Font, System.Drawing.Brushes.Gray, new System.Drawing.PointF(0, 0));
}
else
{
e.Graphics.DrawString(Text, this.Font, new SolidBrush(this.ForeColor) , new System.Drawing.PointF(0, 0));
}
}
protected override void OnTextChanged(EventArgs e)
{
Invalidate();
base.OnTextChanged(e);
}
}
You can tie the feature/behaviour closer to the TextBox control by using extension methods. This simple solution might make it feel more tightly knit:
// NOTE: first parameter "this TextBox thisText"- these are all extension methods.
static public void AssignLabel(this TextBox thisText, Label companionLabel) {
thisText.Tag = companionLabel;
// HOOK UP EVENT AT THIS POINT, WHEN LABEL IS ASSIGNED (.NET 3.x)
thisText.Leave += (Object sender, EventArgs e) => {
LeaveMe(thisText); // Invoke method below.
};
}
static public void FocusText(this TextBox thisText) {
if (! ReferenceEquals(null, thisText.Tag))
(Label)thisText.Tag).Visible = false;
thisText.Focus();
}
static public void LeaveMe(this TextBox thisText) {
if (String.IsNullOrEmpty(thisText.Text))
((Label)thisText.Tag).Visible = true;
}
//etc.
and then use your textbox instances like so:
Label overlay1 = new Label(); // Place these appropriately
Label overlay2 = new Label(); // on top of the text boxes.
Label overlay3 = new Label();
TextBox myTextbox1 = new TextBox();
TextBox myTextbox2 = new TextBox();
TextBox myTextbox3 = new TextBox();
// Note: Calling our extension methods directly on the textboxes.
myTextbox1.AssignLabel(overlay1);
myTextbox1.FocusText();
myTextbox1.LeaveMe();
myTextbox2.AssignLabel(overlay2);
myTextbox2.FocusText();
myTextbox2.LeaveMe();
myTextbox3.AssignLabel(overlay3);
myTextbox3.FocusText();
myTextbox3.LeaveMe();
//etc...
The code is cleaner and applies to all TextBoxes you instantiate.
It relies on the the .Tag property of the TextBox class to store a Label reference into (so each TextBox knows its label), and also extension methods introduced with .NET 3.x which allow us to "attach" methods onto the TextBox class itself to tie your behaviour directly to it.
I took your code and produced almost the same thing with tweaks to turn it into extension methods, and to associate a Label with your Textbox.
If you want to attach the same method to other controls (and not just the text box) then extend the base Control class itself like:
static public void LeaveMe(this Control thisControl) { //...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With