Introduction [^]
This article presents a
UserControl, named PasswordEye, that displays characters in a
TextBox masked by a
PasswordChar masking character. There is a small
Button
with a
BackgroundImage of an eye on the right side of the control. When
the mouse cursor is placed over the eye and a mouse button pressed,
the characters in the TextBox become visible. Upon release of the
mouse button, the characters in the TextBox are again hidden by the
PasswordChar masking character.
In the following discussions, properties that are specified by the
developer are displayed in
BoldMixedCase text.
Variables, used internally by the software are displayed in
italicized_lowercase text.
Table of Contents
The symbol [^] returns the reader
to the top of the Table of Contents.
Visual Properties [^]
The PasswordEye control has a number of properties
that affect the user's visual image. The developer specifies the
control's top-left corner by dragging the control from the
ToolBox to a position on the form. This position becomes
( 0, 0 ) in the control's graphic environment.
The height and width of the control are specified using the
Font and
Maximum_Width properties.
After some computations, the values of a number of other
internal variables are set by the
set_control_properties
method.
The background color of the control and its components (panel,
textbox, and button) is specified by the
BackColor property. The
background color defaults to
Color.White.
The foreground color of the control's textbox component is
specified by the
Forecolor property. The
forecolor color defaults to
Color.Black.
The character used for masking the password is specified using
the
PasswordChar property.
The password masking character defaults to the asterisk (*).
Text displayed in the password TextBox can be retrieved or set by
the
Text property.
Control Properties [^]
The PasswordEye control has the following properties
available to the developer:
Name
| |
Description
|
| | |
BackColor
| | Gets or sets the color of the BackColor of the control's
components. The default value is
Color.White.
|
| | |
Font
| | Gets or sets the Font used in the control's TextBox component.
The default is the Microsoft Sans Serif font family, regular
font style, and font size of 12.
Font controls the
height of the control.
|
| | |
ForeColor
| | Gets or sets the color of the ForeColor of the control's
components. The default value is
Color.Black.
|
| | |
Maximum_Width
| | Gets or sets the maximum width, in characters, of the
control's TextBox.
Maximum_Width only
affects the width of the control. The default value is 20.
|
| | |
MaxLength
| | Gets or sets the maximum number of characters allowed to be
entered into the control's TextBox.
MaxLength only affects
the number of characters that may be entered into the
control's textbox. The default value is 20.
|
| | |
PasswordChar
| | Gets or sets the character used to mask input into the
control's Textbox. The default is the asterisk (*).
|
| | |
Text
| | Gets or sets the text that appears in the control's TextBox.
|
When certain properties are changed, other internal values for
the control are recalculated by the
set_control_properties
method.
Implementation [^]
The PasswordEye control is a UserControl composed of a Panel, a
TextBox, and a Button. Each component has a one pixel buffer
around it.
Note
The control uses Windows coordinates with the x-axis values
increasing to the right and the y-axis values increasing downward.
set_control_properties
is invoked when the value of any property changes
void set_control_properties ( )
{
int button_location_y = 0;
this.Controls.Clear ( );
panel.Controls.Clear ( );
textbox.BackColor = backcolor;
textbox.BorderStyle = BorderStyle.None;
textbox.ForeColor = forecolor;
textbox.Location = new Point ( TEXTBOX_LOCATION_X,
TEXTBOX_LOCATION_Y );
textbox.Size = new Size ( textbox_text_width ( ),
textbox.Height );
button.BackColor = backcolor;
button.BackgroundImage = Properties.
Resources.
PasswordEyeImage;
button.BackgroundImageLayout = ImageLayout.Zoom;
button.FlatStyle = FlatStyle.Flat;
if ( textbox.Height > TEXTBOX_HEIGHT )
{
button.Size = new Size ( BUTTON_HEIGHT,
BUTTON_WIDTH );
button_location_y =
round ( ( double ) ( textbox.Height -
button.Height ) / 2.0 );
}
else
{
button.Size = new Size ( textbox.Height,
textbox.Height );
button_location_y = textbox.Location.Y;
}
button.Location = new Point ( textbox.Location.X +
textbox.Width + 1,
button_location_y );
panel.BackColor = backcolor;
panel.Location = new Point ( PANEL_LOCATION_X,
PANEL_LOCATION_Y );
panel.Size = new Size (
( textbox.Location.X + 1 ) +
( textbox.Width + 1 ) +
( button.Width + 1 ),
( textbox.Height + 2 ) );
panel.Controls.Add ( textbox );
panel.Controls.Add ( button );
this.Controls.Add ( panel );
this.Width = panel.Width + 2;
this.Height = panel.Height + 2;
trigger_passwordeye_properties_changed_event ( );
}
set_control_properties
performs the following actions, in order:
- Clears the control's
ControlCollection thus removing existing textbox,
button, or panel components from the control.
- Clears the panel's ControlCollection thus removing
existing textbox and button components from the panel.
- Revises the properties of the control's TextBox.
- Revises the properties of the control's Button.
- Revises the properties of the control's Panel.
- Adds the revised TextBox and Button back into the Panel's
ControlCollection.
- Adds the revised Panel back into the control's
ControlCollection.
- Adjusts the size of the control.
- Invokes
trigger_passwordeye_properties_changed_event
to notify any subscriber of changes to the control's and control
components' properties.
The helper function
round is:
int round ( double control_value )
{
return ( ( int ) ( control_value + 0.5 ) );
}
Handling Events [^]
Many programming languages have a mechanism whereby events of
interest can be signaled to interested parties. C# has such a
mechanism and, because PasswordEye is implemented in C#, this
discussion will be limited to that language.
PasswordEyePropertiesChanged [^]
PasswordEye usefulness is increased if it could tell (signal)
its parent that the user made a change to PasswordEye properties.
To signal these events, PasswordEye contains the declaration of
the
PasswordEyePropertiesChanged
event.
public delegate void PasswordEyePropertiesChangedHandler (
Object sender,
PasswordEyePropertiesChangedEventArgs e );
public event PasswordEyePropertiesChangedHandler
PasswordEyePropertiesChanged;
The
delegate
PasswordEyePropertiesChangedHandler
defines the signature of a method that will be invoked by the
PasswordEyePropertiesChanged
event. The event handler is expected to have two arguments: sender
and a custom EventArgs,
PasswordEyePropertiesChangedEventArgs.
The latter argument is defined in the following class.
public class PasswordEyePropertiesChangedEventArgs
{
public Color backcolor;
public Button button;
public Control control;
public Color forecolor;
public int maximum_width;
public Panel panel;
public TextBox textbox;
public PasswordEyePropertiesChangedEventArgs (
Color backcolor,
Button button,
Control control,
Color forecolor,
int maximum_width,
Panel panel,
TextBox textbox )
{
this.backcolor = backcolor;
this.button = button;
this.control = control;
this.forecolor = forecolor;
this.maximum_width = maximum_width;
this.panel = panel;
this.textbox = textbox;
}
}
PasswordEyePropertiesChangedEventArgs
returns the current background and foreground colors, button, panel,
and textbox components, the current maximum_width, and the control,
itself. Whenever PasswordEye detects a change in the value of any
control component properties, it invokes the
trigger_passwordeye_properties_changed_event
method.
void trigger_passwordeye_properties_changed_event ( )
{
if ( PasswordEyePropertiesChanged != null )
{
PasswordEyePropertiesChanged (
this,
new PasswordEyePropertiesChangedEventArgs (
backcolor,
button,
this,
forecolor,
textbox_maximum_width,
panel,
textbox ) );
}
}
The
PasswordEyePropertiesChanged
event may have zero or more subscribers. The test
if ( PasswordEyePropertiesChanged != null )
is made to insure that there is at least one subscriber to the
PasswordEyePropertiesChanged
event. Failure to make this test could cause an exception, something
to be avoided in a user control.
If a class wishes to be notified of a change in the value of the
PasswordEye properties, it must
register an event handler. In the
Demonstration program there is a single
PasswordEye instance. The
Demonstration program subscribes to the
event handler of this instance.
This is accomplished by first declaring that the method
password_PE_PasswordEyePropertiesChanged
is to be used to capture the event:
password_PE.PasswordEyePropertiesChanged +=
new PasswordEye.
PasswordEye.
PasswordEyePropertiesChangedHandler (
password_PE_PasswordEyePropertiesChanged );
The
PasswordEyePropertiesChanged
method is declared as:
void password_PE_PasswordEyePropertiesChanged (
object sender,
PasswordEye.PasswordEyePropertiesChangedEventArgs e )
{
control_status =
String.Format (
" Textbox: Location {3:D3}, {4:D3}" +
Environment.NewLine +
" Size {5:D3}, {6:D3}" +
Environment.NewLine +
" Text: {18}" +
Environment.NewLine +
" Font:" +
Environment.NewLine +
" Size {0}" +
Environment.NewLine +
" Name {1}" +
Environment.NewLine +
" Style {2}" +
Environment.NewLine +
" MaxLength: {17}" +
Environment.NewLine +
" Password Char: {19}" +
Environment.NewLine +
" Max_Width: {24}" +
Environment.NewLine +
" Button: Location {7:D3}, {8:D3}" +
Environment.NewLine +
" Size {9:D3}, {10:D3}" +
Environment.NewLine +
" Panel: Location {11:D3}, {12:D3}" +
Environment.NewLine +
" Size {13:D3}, {14:D3}" +
Environment.NewLine +
" Colors: Back {15}" +
Environment.NewLine +
" Fore {16}" +
Environment.NewLine +
" Control: Location {20:D3}, {21:D3}" +
Environment.NewLine +
" Size {22:D3}, {23:D3}",
e.textbox.Font.Size,
e.textbox.Font.FontFamily.ToString ( ),
e.textbox.Font.Style.ToString ( ),
e.textbox.Location.X,
e.textbox.Location.Y,
e.textbox.Size.Width,
e.textbox.Size.Height,
e.button.Location.X,
e.button.Location.Y,
e.button.Size.Width,
e.button.Size.Height,
e.panel.Location.X,
e.panel.Location.Y,
e.panel.Size.Width,
e.panel.Size.Height,
e.backcolor.ToString ( ),
e.forecolor.ToString ( ),
e.textbox.MaxLength,
e.textbox.Text,
e.textbox.PasswordChar,
e.control.Location.X,
e.control.Location.Y,
e.control.Size.Width,
e.control.Size.Height,
e.maximum_width );
display_information ( );
}
The Eye [^]
The user interacts with the PasswordEye by typing a password into
the control. If the user wants to see what has already been entered,
the user clicks on the image of an eye on the right side of the
control. The user's interactions are detected by the event handlers
for the
OnMouseDown and
OnMouseUp events.
button_MouseDown Event Handler [^]
button_MouseDown
is the handler for the OnMouseDown event.
void button_MouseDown ( object sender,
MouseEventArgs e )
{
base.OnMouseDown ( e );
textbox.PasswordChar = PASSWORD_VISIBLE;
}
The
button_MouseDown
event handler is classic.
- Call the base class's
OnMouseDown method so
that all registered delegates receive the event.
- Set the textbox PasswordChar to PASSWORD_VISIBLE ('\0'). This
has the effect of showing the current contents of the textbox.
button_MouseUp Event Handler [^]
button_MouseUp
handles the OnMouseUp event.
void button_MouseUp ( object sender,
MouseEventArgs e )
{
base.OnMouseUp ( e );
textbox.PasswordChar = PASSWORD_HIDDEN;
}
When the user releases the mouse button, the
button_OnMouseUp event
handler is invoked. This handler simply sets the textbox
PasswordChar to PASSWORD_HIDDEN ('*'), effectively hiding what has
been typed into the textbox.
TextBox Events [^]
textbox_TextChanged Event Handler [^]
Each character typed into the PasswordEye textbox triggers the
textbox_TextChanged event.
void textbox_TextChanged ( object sender,
EventArgs e )
{
base.OnTextChanged ( e );
trigger_passwordeye_properties_changed_event ( );
}
All that
textbox_TextChanged does is
to trigger the
PasswordEyePropertiesChangedEvent
event. Any subscriber
to that event will obtain the current properties of the
PasswordEye control, including the characters typed into the
password textbox.
textbox_FontChanged Event Handler [^]
There are two properties that define the size of the PasswordEye
control:
Font and
Maximum_Width. Both are
provided for the developer. In the
Demonstration program both values may
be changed dynamically. Changes in either of the properties' values
will cause an invocation of
set_control_properties. In
addition, any dynamic change to
Font will trigger the
textbox_FontChanged event
handler.
void textbox_FontChanged ( object sender,
EventArgs e )
{
base.OnFontChanged ( e );
set_control_properties ( );
}
Demonstration [^]
The demonstration program shows how the PasswordEye control works.
It allows its user to play around with the control's properties. As
property values change, their values are displayed in the
RichTextBox.
Conclusion [^]
This article has presented a UserControl that displays a modern
password control.
References [^]
Development Environment [^]
The PasswordEye control was developed in the following environment:
| Microsoft Windows 7 Professional Service Pack 1 |
| Microsoft Visual Studio 2008 Professional |
| Microsoft .Net Framework Version 3.5 SP1 |
| Microsoft Visual C# 2008 |
History [^]
09/29/2013
| | Original Article.
|
09/30/2013
| | Made typographic corrections.
|