Fields validation in winforms - c#

Is there a shortcut in validating fields in winforms? For example a particular textBox is required to be filled up before saving a record. What I always do is I check first all the required fields programatically before saving. Example:
protected bool CheckFields()
{
bool isOk = false;
if(textBox1.Text != String.Empty)
{
isOk = true;
}
return isOk;
}
private void btnSave_Click(object sender, EventArgs e)
{
if(CheckFields())
{
Save();// Some function to save record.
}
}
Is there a counter part of Validator in ASP.Net in winforms? Or any other way around...

Here is one approach:
private List<Control> m_lstControlsToValidate;
private void SetupControlsToValidate()
{
m_lstControlsToValidate = new List<Control>();
//Add data entry controls to be validated
m_lstControlsToValidate.Add(sometextbox);
m_lstControlsToValidate.Add(sometextbox2);
}
private void ValidateSomeTextBox()
{
//Call this method in validating event.
//Validate and set error using error provider
}
Private void Save()
{
foreach(Control thisControl in m_lstControlsToValidate)
{
if(!string.IsNullOrEmpty(ErrorProvider.GetError(thisControl)))
{
//Do not save, show messagebox.
return;
}
}
//Continue save
}
EDIT:
For each control in m_lstControlsToValidate you need to write the validation method that would be fired in Validating event.
ErrorProvider.GetError(thisControl) will return some errortext or emptystring. Empty string means the control is fine. Else the control contains some error and we abort the save operation.
We do this on all the controls in m_lstControlsToValidate. If all controls are error free we continue with save else abort.

Not really, in Win Form you should use the Control.Validating Event for validation when user is working on the form. But for saving validation You have write code that check that all data are correctly inserted by user. For instance you can create a mandatory TextBox, and iterate over all form controls looking for this type of control and check that user has inputed some text.

Use a validation control. They are the best thing to use.
Also,
protected bool CheckFields()
{
bool isOk = false;
if(textBox1.Text != String.Empty)
{
isOk = true;
}
return isOk;
}
Can be shorterned considerably to:
protected bool CheckFields()
{
return textBox1.Text != String.Empty;
}

Related

Is it possible to tell if the Text change on an entry was from code or from the UI?

I am working on a Xamarin project and I need to be able to tell if the changes that occur to the text in an Entry view are from the code or from the UI, is this possible in Xamarin? or is there a known work around to do this.
I know about the OnTextChanged event but this only tells you that the Text property has changed, and gives you access to the old and new value of the Text property. It does not differentiate between different causes of text change.
You can get some idea from this thread, check if the entry is focused to differentiate between different causes of text change:
public MainPage()
{
InitializeComponent();
myEntry.TextChanged += MyEntry_TextChanged;
}
private void MyEntry_TextChanged(object sender, TextChangedEventArgs e)
{
var entry = sender as Entry;
if (entry.IsFocused)
{
//change from UI
Console.WriteLine("change from UI");
}
else{
//change from code
Console.WriteLine("change from code");
}
}
Update: The better way to solve op's problem:
You can set a flag yourself that tells your code to ignore the event. For example:
private bool ignoreTextChanged;
private void textNazwa_TextCanged(object sender, EventArgs e)
{
if (ignoreTextChanged) return;
}
Create a method and use this to set the text instead of just calling Text = "...";::
private void SetTextBoxText(TextBox box, string text)
{
ignoreTextChanged = true;
box.Text = text;
ignoreTextChanged = false;
}
Refer: ignoreTextChanged
you can use EntryRenderer to detect keypress event and use that flag to detect the change by code or by UI.
Here are the step:
- Exetend your entry control with new event OnTextChangeByUI
- Write custom render for both platform
e.g for android it will be something like this
public class ExtendedEntryRender : EntryRenderer
{
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (Control != null)
{
Control.KeyPress += ((Entry)Element).OnTextChangeByUI;
}
}
}

checking the pressed key when closing datetimepicker

When datetimepicker is used, sometimes user does not do any changes and close the datetimepicker.
After closing the datetimepicker my program checks if the date is suitable with the rest of data. I want to prevent this checking if datetimepicker is closed by escape or clicking somewhere else.
Is it possible to detect if datetimepicker is closed without choosen a date?
I use close-up property and EventArgs.
I think the problem here is that the ValueChanged event fires even when the User is just browsing through the calendar. I don't see a really obvious way handle it. However the following code will do a decent job of ignoring value changes events between the DropDown and CloseUp events.
bool UserIsJustLooking = false;
private void dateTimePicker1_DropDown(object sender, EventArgs e)
{
UserIsJustLooking = true;
dateTimePicker1.Tag = dateTimePicker1.Value;
}
private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
{
if (UserIsJustLooking)
{
// the user is just browsing the dates (ignore these value changed events because they aren't real)
}
else
{
Console.WriteLine("The value changed without opening, new value is " + dateTimePicker1.Value.ToString());
}
}
private void dateTimePicker1_CloseUp(object sender, EventArgs e)
{
UserIsJustLooking = false;
if ((DateTime)dateTimePicker1.Tag == dateTimePicker1.Value)
{
// User did not really change the value
}
else
{
Console.WriteLine("User selected a new value: " + dateTimePicker1.Value);
}
}
You can use the built-in validation methods:
private void DateTimePicker_Validating(object sender, CancelEventArgs e)
{
//validation logic
//if valid
e.Cancel = false;
//else
e.Cancel = true;
}
Setting the CancelEventArgs.Cancel to true will prevent the control from loosing focus.
You need to attach this to your DateTimePicker Validating event
After the illumination of David as I could not resolve the problem with
if ((DateTime)dateTimePicker1.Tag == dateTimePicker1.Value)
I created another version.
In public partial class I added these
public bool EscPressed = false;
public string calTag = DateTime.Now.ToString("d");
I wrote this method
private void cal_Close(object sender, EventArgs e)
{
EscPressed = false;
if (calTag == cal.Value.ToString("d"))
EscPressed = true;
else
EscPressed = false;
cal.Visible = false;
if (EscPressed)
return;
calTag = cal.Value.ToString("d");
_textBox[1].Text = _textBox1[1].Text = calTag;
CheckDate();
}
PS: Checkdate() is a method which checks if date is well chosen or not

Errorprovider c# winforms

Im working with errorprovider in a c# winforms application.
Now I want to have a "double" validation. Once on the textfields directly, so the user sees that he has made some errors, and once on the button itself. So when there are still errors, the "save" button will keep greyed out or "disabled".
Because I don't want to block my user when he is making an error, and I want him to be able to make the changes whenever he wants im using the event "leave" or on focus lost. This because otherwise I noticed you cannot go to another field, until you changed your error.
So, now the code:
private void txtFirstname_Leave(object sender, EventArgs e)
{
if (!InputChecks.IsFilledIn(txtFirstname.Text))
{
errorProvider1.SetError(txtFirstname, "Firstname needs to be filled in!");
isValidated = false;
}
else
{
errorProvider1.SetError(txtFirstname, "");
isValidated = true;
}
}
So far, so good. The error provider works correctly and my user can edit whenever he wants.
public void setSaveButton()
{
if (isValidated == true)
{
btnSave.Enabled = true;
}
else
{
btnSave.Enabled = false;
}
}
bool isValidated;
private void btnSave_Click(object sender, EventArgs e)
{
if (isValidated == true)
{
employeePresenter.addEmployee(txtFirstname.Text, txtLastname.Text, txtUsername.Text, txtPassword.Text);
}
}
This was still okey in my head. BUT, as I give the ability to the user to change the issues whenever they want, this doesn't work. I tried to put the method "setSaveButton()" under "isvalidated" but this is not working either. Because of the focus lost.
Anyone has a better idea for this? I have been looking on google and the only things i found was a single validation with the errorprovider, or the event validating. But these events don't allow users to edit their errors whenever they want. It blocks them into one particular text field.
You don't need to make the save button disabled. It's enough to check ValidateChildren method of your form and if it returned false, it means there is some validation error. To use this approach you should remember to set e.Cancel = true in Validating event of the control when you set an error for control.
Also to let the user to move between controls even if there is an error, set AutoValidate property of your Form to EnableAllowFocusChange in designer or using code:
this.AutoValidate = System.Windows.Forms.AutoValidate.EnableAllowFocusChange;
Code for Validation:
private void txtFirstname_Validating(object sender, CancelEventArgs e)
{
if (string.IsNullOrEmpty(this.txtFirstname.Text))
{
this.errorProvider1.SetError(this.txtFirstname, "Some Error");
e.Cancel = true;
}
else
{
this.errorProvider1.SetError(this.txtFirstname, null);
}
}
private void btnSave_Click(object sender, EventArgs e)
{
if (this.ValidateChildren())
{
//Here the form is in a valid state
//Do what you need when the form is valid
}
else
{
//Show error summary
}
}

Textbox validation in a Windows Form

I want to put a validation that the user always enters a value in the textbox before submiting the form. But the check that I have put allows user to enter white spaces and continue submitting the form.
So, how to put the check so that the user in not able to submit the form if there are only white spaces in the textbox.
You can make your own custom validation function. This may be very naive, but somehow it will work.
private bool WithErrors()
{
if(textBox1.Text.Trim() == String.Empty)
return true; // Returns true if no input or only space is found
if(textBox2.Text.Trim() == String.Empty)
return true;
// Other textBoxes.
return false;
}
private void buttonSubmit_Click(object sender, EventArgs e)
{
if(WithErrors())
{
// Notify user for error.
}
else
{
// Do whatever here... Submit
}
}
in NET4.0 there is a nice function
if(string.IsNullOrWhiteSpace(textBox1.Text))
{
//raise your validation exception
}
else {
//go to submit
}
It can be easily be done using error provider here is the code.Error Provider you can find in your toolbox.
private void btnsubmit_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(txtname.Text))
{
txtname.Focus();
errorProvider1.SetError(txtname, "Please Enter User Name");
}
if (string.IsNullOrEmpty(txtroll.Text)) {
txtroll.Focus();
errorProvider1.SetError(txtroll, "Please Enter Student Roll NO");
}
}
Here is output image

How to determine whether TextChanged was triggered by keyboard in C#?

I have a method
private void textBoxPilot_TextChanged(object sender, TextChangedEventArgs e)
{ ... }
where the textbox in question takes a search string from the user and populates a ListBox with the results on every keystroke.
Subsequently, when an item is picked from the ListBox, I would like the choice reflected in the same Textbox. However, I don't want to trigger the search mechanism, which would cause the Listbox to forget its selection.
How can I determine whether the TextChanged event was triggered by the user (via they keyboard or maybe copy/paste) or by another method using textBoxPilot.Text = "Pilot name";?
Thanks.
bit of a hack, but....
public class MyForm : Form
{
private bool _ignoreTextChanged;
private void listView1_SelectionChanged( object sender, EventArgs e )
{
_ingnoreTextChanged = true;
textBoxPilot.Text = listView1.SelectedValue.ToString(); // or whatever
}
private void textBoxPilot_TextChanged( object sender, TextChangedEventArgs e )
{
if( _ignoreTextChanged )
{
_ignoreTextChanged = false;
return;
}
// Do what you would normally do.
}
}
A disabled control will not fire a event. So two options are either always disable update the text then re-enable or create a derived class wrapper (using this method you could still do data binding)
class myClass : TextBox
{
public virtual string TextWithoutEvents
{
get
{
return base.Text;
}
set
{
bool oldState = Enabled;
Enabled = false;
base.Text = value;
Enabled = oldState;
}
}
}
If the user selects "Pilot name" from the list, you set the text box to "Pilot name". This will cause the list box to select "Pilot name". So the selection should be kept. You just have to break the recursion.
In my scenario where user has to type in text to trigger auto-complete and we didn't want a re-trigger when the auto-complete changes the text again, I used the text lengths. This won't work if user copy/pastes and therefore adds more than 1 character at a time with the keyboard.
private void HandleTextChanged(object sender, TextChangedEventArgs e){
var oldText = e.OldTextValue;
var newText = e.NewTextValue;
// Assuming text changed from keyboard is always 1 character longer,
// ignore this text changed event if new text > 1 character longer.
if (newText.Length > oldText.Length + 1) {
return;
}
...
}
In your scenario, if you always know the values you want to skip, then you could check for them instead:
if (newText == "Pilot name") {
return;
}
or
if (myListOfNamesToIgnore.Contains(newText)) {
return;
}

Categories