Created
February 28, 2020 16:18
-
-
Save bpmct/3a0ae3018476dea85a14df74e72685b4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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