Skip to content

Instantly share code, notes, and snippets.

@bpmct
Created February 28, 2020 16:18
Show Gist options
  • Save bpmct/3a0ae3018476dea85a14df74e72685b4 to your computer and use it in GitHub Desktop.
Save bpmct/3a0ae3018476dea85a14df74e72685b4 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace EditPerson
{
// the partial keyword allows us to split the definition of a class over multiple files
public partial class PersonEditForm : Form
{
// this is the constructor of our PersonEditForm class derived from the Form parent class
// our class has the following objects added to it:
// this.typeLabel : Label control
// this.typeComboBox : ComboBox control
// this.nameLabel : Label control
// this.nameText : TextBox control
// this.emailLabel : Label control
// this.emailText : TextBox control
// this.ageLabel : Label control
// this.ageText : TextBox control
// this.licLabel : Label control
// this.licText : TextBox control
// this.gpaLabel : Label control
// this.gpaText : TextBox control
// this.specialtyLabel : Label control
// this.specText : TextBox control
// this.cancelButton : Button control
// this.okButton : Button control
// this.errorProvider : ErrorProvider control
public PersonEditForm(PersonEditForm personn, Form parentForm)
{
InitializeComponent();
// default the OK button to be disabled
// and only enable it if all text fields are valid
this.okButton.Enabled = false;
// most Form controls have a Tag field which is a System.Object type
// and can be used to store any property
// loop through all of the controls on the form
foreach (Control control in this.Controls)
{
// we will use the Tag field to indicate if the field is valid or not
// initialize Tag to false to indicate invalid
control.Tag = false;
}
if (parentForm != null)
{
this.Owner = parentForm;
this.CenterToParent();
}
// the following excerpts are from "Windows Forms Controls" on myCourses
// to add Validating and TextChanged event handlers to the TextBox Controls
/***********************************************************************************
Validating Event
Occurs when the object is leaving scope (ie. tabbing out of the field or the user clicked another field or button)
Accepts the event handler CancelEventHandler() because the primary purpose of Validating is to determine whether
this event should cause the focus to leave the current control and enter the next control
(if CausesValidation == True for the next control). If the validation fails, then the navigation event is
cancelled and the current control stays in focus.
Example for adding the delegate method:
this.objectName.Validating += new CancelEventHandler(this.ObjectName__Validating);
The CancelEventHandler() delegate method must accept the following parameters:
private void ObjectName__Validating(object sender, CancelEventArgs e)
By convention, the delegate methods are named:
ObjectName_EventName()
Important Fields in sender (TextBox)
TextBox tb = (TextBox)sender;
tb.Text: validate for certain contents before allowing user to exit the field
Important Fields in CancelEventArgs
e.Cancel: a boolean to indicate whether the event should be cancelled or not. If set to true, then the current TextBox will stay in focus.
************************************************************************************/
// refer to line #75 for how to add the TxtBoxEmpty__Validating delegate function to the Validating event handler
// we want the same delegate function to be called for the following 6 fields
// TxtBoxEmpty__Validating is defined below
this.nameText.Validating += new CancelEventHandler(TxtBoxEmpty__Validating);
this.emailText.Validating += new CancelEventHandler(TxtBoxEmpty__Validating);
this.ageText.Validating += new CancelEventHandler(TxtBoxEmpty__Validating);
this.licText.Validating += new CancelEventHandler(TxtBoxEmpty__Validating);
this.gpaText.Validating += new CancelEventHandler(TxtBoxEmpty__Validating);
this.specText.Validating += new CancelEventHandler(TxtBoxEmpty__Validating);
/***********************************************************************************
TextChanged
Occurs when the contents of Text changes (ie. TextBox.Text)
Accepts the empty EventHandler() delegate because the event is limited to only the current control.
Example for adding the delegate method:
this.objectName.TextChanged += new EventHandler(this.ObjectName__TextChanged);
The EventHandler delegate method must have the following signature:
private void ObjectName__TextChanged(object sender, EventArgs e)
Important Fields in sender
TextBox tb = (TextBox)sender;
tb.Text: the current text in the TextBox
Important Fields in EventArgs
None.
************************************************************************************/
// refer to line #107 for how to add the TxtBoxEmpty__TextChanged delegate function to the Validating event handler
// finish coding the delegate method TxtBoxEmpty__TextChanged below
// we want the same delegate function to be called for the following 6 fields
this.nameText.TextChanged += new EventHandler(TxtBoxEmpty__TextChanged);
this.emailText.TextChanged += new EventHandler(TxtBoxEmpty__TextChanged);
this.ageText.TextChanged += new EventHandler(TxtBoxEmpty__TextChanged);
this.licText.TextChanged += new EventHandler(TxtBoxEmpty__TextChanged);
this.gpaText.TextChanged += new EventHandler(TxtBoxEmpty__TextChanged);
this.specText.TextChanged += new EventHandler(TxtBoxEmpty__TextChanged);
/*
KeyPress Event for TextBox fields
Occurs when the user presses a key sequence which generates a character(shift + A for example) within the control
Accepts the KeyPressEventHandler() delegate, whose method must have the following signature:
private void ObjectName__KeyPress(object sender, KeyPressEventArgs e)
Example for adding the delegate method:
this.objectName.KeyPress += new KeyPressEventHandler(this.ObjectName__KeyPress);
Important Fields in sender:
TextBox tb = (TextBox)sender;
tb.Text: the current text in the TextBox
Important Fields in KeyPressEventArgs
e.KeyChar: gets or sets the character just pressed allowing you to change, suppress or pass - through each character
e.Handled: a boolean to indicate whether the delegate's method "handled" the keypress. If it is set to true, then .NET will not process the keypress (ie. the keyboard buffer will be cleared).
*/
// finish coding the TxtNum__KeyPress function below, which enforces digits-only in the Age, License and GPA fields,
// and allows 1 decimal point in the GPA field.
// using the example code on line #54, add the KeyPressEventHandler delegate function TxtNum__KeyPress for the following 3 numeric fields:
this.ageText.KeyPress += new KeyPressEventHandler(this.TxtNum__KeyPress);
this.licText.KeyPress += new KeyPressEventHandler(this.TxtNum__KeyPress);
this.gpaText.KeyPress += new KeyPressEventHandler(this.TxtNum__KeyPress);
/*
SelectedIndexChanged Event for ComboBox Controls
Occurs when the user changes the ComboBox value
Accepts the empty EventHandler() delegate because the event is limited to only the current control.
Example for adding the delegate method:
this.objectName.SelectedIndexChanged += new EventHandler(this.ObjectName__SelectedIndexChanged);
The EventHandler delegate method must have the following signature:
private void ObjectName__SelectedIndexChanged(object sender, EventArgs e)
Important Fields in sender
ComboBox cb = (ComboBox) sender;
cb.SelectedIndex: the 0-based index of the selected item
cb.SelectedItem: the string of the display value of the selected item
Important Fields in EventArgs
None.
*/
// finish coding the TypeComboBox__SelectedIndexChanged delegate function below based on the comments
// using line #81 add the Event Handler to the typeComboBox control
this.typeComboBox.SelectedIndexChanged += new EventHandler(this.TypeComboBox__SelectedIndexChanged);
// initialize the typeComboBox SelectedIndex to 0 (Student)
typeComboBox.SelectedIndex = 0;
/* Increase the size of the form by changing:
MaximumSize: 842,478
Size: 842,478
Place 7 radio buttons on the form to the right of the Combo Box, Name and Email fields.
They should be defined as:
(Name): himRadioButton herRadioButton themRadioButton
Text: Him Her Them
(Name): froshRadioButton sophRadioButton juniorRadioButton seniorRadioButton
Text: Freshman Sophomore Junior Senior
Run the application, and notice how you can only select 1 Radio Button at a time.
We want to be able to select 1 Gender Radio Button, and 1 Class Year Radio Button.
We can do this by putting the Radio Buttons in Group Boxes.
Add a GroupBox control to the form:
(Name): genderGroupBox
Text: Gender
Drag the 3 Gender Radio Buttons onto the Group Box.
Run the application again and notice how you can now select one Gender and one Class Radio Button.
Your next homework will be to add Radio Buttons to the form.
The CheckedChanged Event for Radio Buttons
Occurs when the Checked status changes.
Note that this will be called when the currently selected RadioButton unchecks and the new RadioButton becomes checked.
Accepts the empty EventHandler() delegate because the event is limited to only the current control.
Example for adding the delegate method:
this.objectName.CheckedChanged += new EventHandler(this.ObjectName__CheckedChanged);
The EventHandler delegate method must have the following signature:
private void ObjectName__CheckedChanged(object sender, EventArgs e)
Important Fields in sender
RadioButton rb = (RadioButton)sender;
rb.Checked: the current checked state of the RadioButton control.
Important Fields in EventArgs
None.
*/
// finish the GenderRadioButton__CheckedChanged delegate function below
// and using the code example on line #130, add the EventHandler to the Radio Buttons
this.himRadioButton.CheckedChanged += new EventHandler(this.GenderRadioButton__CheckedChanged);
this.herRadioButton.CheckedChanged += new EventHandler(this.GenderRadioButton__CheckedChanged);
this.themRadioButton.CheckedChanged += new EventHandler(this.GenderRadioButton__CheckedChanged);
this.froshRadioButton.CheckedChanged += new EventHandler(this.GradeRadioButton__CheckedChanged);
this.sophRadioButton.CheckedChanged += new EventHandler(this.GradeRadioButton__CheckedChanged);
this.juniorRadioButton.CheckedChanged += new EventHandler(this.GradeRadioButton__CheckedChanged);
this.seniorRadioButton.CheckedChanged += new EventHandler(this.GradeRadioButton__CheckedChanged);
}
// a method to check the valid state of all of the text fields to enable or disable the OK button
private void ValidateAll()
{
// enable or disable the OK button based on the valid state of all of the fields
//validates fields based on the type
bool textFieldsEntered =
(bool)this.nameText.Tag &&
(bool)this.emailText.Tag &&
(bool)this.ageText.Tag &&
(bool)this.gpaText.Tag;
bool uniqueFieldEntered;
// check if student or teacher. SelectedIndex = 0 is student
if (typeComboBox.SelectedIndex == 0)
{
uniqueFieldEntered = (bool)this.gpaText.Tag &&
//validate grade year with xor
(
this.froshRadioButton.Checked ^
this.sophRadioButton.Checked ^
this.juniorRadioButton.Checked ^
this.seniorRadioButton.Checked
);
}
else
uniqueFieldEntered = (bool)this.specText.Tag;
//Using xor just in case two buttons get checked
bool genderRadioEntered =
himRadioButton.Checked ^
herRadioButton.Checked ^
themRadioButton.Checked;
//Enable/disable the button depending on our
this.okButton.Enabled =
textFieldsEntered &&
uniqueFieldEntered &&
genderRadioEntered;
}
// this delegate method for the Validating event prevents the user from leaving a TextBox if it is empty
private void TxtBoxEmpty__Validating(object sender, CancelEventArgs e)
{
// declare a TextBox reference variable set to the sender object parameter cast as a TextBox
TextBox tb = (TextBox)sender;
// if the Length of the Text in the TextBox control is 0
if (tb.Text.Length == 0)
{
// display an error next to the field that it cannot be empty
this.errorProvider.SetError(tb, "This field cannot be empty.");
// set the return flag to .NET to prevent leaving the field
e.Cancel = true;
// set the control as having invalid data
tb.Tag = false;
}
else
{
// otherwise there is data in the field
// clear any error message associated with this field
this.errorProvider.SetError(tb, null);
// indicate that .NET can leave the field
e.Cancel = false;
// set the control as having valid data
tb.Tag = true;
}
// check if the OK button can be enabled now
ValidateAll();
}
// this delegate method for the TextChanged event checks if the user changed the contents of the TextBox to be empty
// this method is called any time the contents of the TextBox changes
// write the missing code based on the Validating method above
private void TxtBoxEmpty__TextChanged(object sender, EventArgs e)
{
// declare a TextBox reference variable set to the sender object parameter cast as a TextBox
TextBox tb = (TextBox)sender;
// if the Length of the Text in the TextBox control is 0
if (tb.Text.Length == 0)
{
// display an error next to the field that it cannot be empty
this.errorProvider.SetError(tb, "This field cannot be empty.");
// set the control as having invalid data
//e.Cancel = true;
tb.Tag = false;
}
else
{
// otherwise there is data in the field
// clear any error message associated with this field
this.errorProvider.SetError(tb, null);
// set the control as having valid data
//e.Cancel = false;
tb.Tag = true;
}
// check if the OK button can be enabled now
ValidateAll();
}
private void GradeRadioButton__CheckedChanged(object sender, EventArgs e)
{
//no need for special validation at this time, we just need to run our ValidateAll()
ValidateAll();
}
private void GenderRadioButton__CheckedChanged(object sender, EventArgs e)
{
// using line #136 declare Radio Button reference variable for object passed in
RadioButton rb = (RadioButton)sender;
// if the reference variable is the himRadioButton
if (rb == himRadioButton)
{
// if the Radio Button Checked field is false
if (rb.Checked == false)
{
// remove the "Mr." prefix from nameText.Text
// using nameText.Text = nameText.Text.Replace("Mr. ","");
nameText.Text = nameText.Text.Replace("Mr. ", "");
}
else
{
// the Radio Button has been selected
// add "Mr. " prefix to Name.Text
nameText.Text = nameText.Text.Insert(0, "Mr. ");
}
}
// if the reference variable is the herRadioButton
if (rb == herRadioButton)
{
// if the Radio Button Checked field is false
if (rb.Checked == false)
{
// remove the "Ms." prefix from nameText.Text
// using nameText.Text = nameText.Text.Replace("Ms. ","");
nameText.Text = nameText.Text.Replace("Ms. ", "");
}
else
{
// the Radio Button has been selected
// add "Ms. " prefix to Name.Text
nameText.Text = nameText.Text.Insert(0, "Ms. ");
}
}
// if the reference variable is the themRadioButton
if (rb == themRadioButton)
{
// if the Radio Button Checked field is false
if (rb.Checked == false)
{
// remove the "Gentleperson " prefix from nameText.Text
// using nameText.Text = nameText.Text.Replace("Gentleperson ","");
nameText.Text = nameText.Text.Replace("Gentleperson ", "");
}
else
{
// the Radio Button has been selected
// add "Gentleperson " prefix to Name.Text
nameText.Text = nameText.Text.Insert(0, "Gentleperson ");
}
}
// check if the OK button can be enabled now
ValidateAll();
}
// the Event Handler for changing the typeComboBox value (Student or Teacher)
// if it's set to Student, show the GPA label and field, but not the Specialty label and field
// if it's set to Teacher, show the Specialty label and field, but not the GPA label and field
private void TypeComboBox__SelectedIndexChanged(object sender, EventArgs e)
{
// refer to line #83 for code to set local ComboBox reference variable
ComboBox cb = (ComboBox)sender;
// the ComboBox SelectedIndex = 0 (Student)
if (cb.SelectedIndex == 0)
{
// set specText and specialtyLabel Visible field = false
specText.Visible = false;
specialtyLabel.Visible = false;
// set gpaText and gpaLabel Visible field = true
gpaText.Visible = true;
gpaText.Visible = true;
}
else // else Teacher is selected
{
// set specText and specialtyLabel Visible field = true
specText.Visible = true;
specialtyLabel.Visible = true;
// set gpaText and gpaLabel Visible field = false
gpaText.Visible = false;
gpaText.Visible = false;
}
// check if the OK button can be enabled now
ValidateAll();
}
private void TxtNum__KeyPress(object sender, KeyPressEventArgs e)
{
// A key was pressed in the associated number field
// only allow digits or a single '.' for the gpa field
// refer to line #54 to create a TextBox reference variable, and explicitly cast the object parameter as a TextBox
// which is the TextBox that the user typed a character in
TextBox tb = (TextBox)sender;
// e.KeyChar contains the character that was pressed
// if a numeric character was entered or backspace was entered
// Char.IsDigit(char) checks if a char is a digit
// '\b' is the character code for backspace
if (Char.IsDigit(e.KeyChar) || e.KeyChar == '\b')
{
// .NET should continue to handle the keystroke (ie. add it to the textbox)
// set e.Handled to indicate that we did not handle it
this.errorProvider.SetError(tb, null);
e.Handled = false;
}
else
{
// assume that the keystroke can be flagged as being handled by us
// (ie. drop the keystroke from the .NET buffer and don't show it in the textbox)
// if the active control is the GPA field gpaText
// then allow one '.'
if (tb.Name == "gpaText")
{
// if they entered '.' and it is not already in gpaText.Text
if (e.KeyChar == '.' && !tb.Text.Contains("."))
{
e.Handled = false;
this.errorProvider.SetError(tb, null);
}
else
{
e.Handled = true;
this.errorProvider.SetError(tb, "Please enter a number and one decimal point.");
}
}
else
{
e.Handled = true;
this.errorProvider.SetError(tb, "Please enter a number");
}
}
// check if the OK button can be enabled now
ValidateAll();
}
private void okButton_Click(object sender, EventArgs e)
{
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment