Data validation and list of errors within one message box c# - c#

Hope you all well. I would like to ask you for an advise.
I am looking for a way to validate a data before OnClick button gets executed.
I do have few ComboBoxes with some data to choose from. Currently I have used some solution, which does look quite "dirty" and I am not happy about it.
Currently I am using something similar to this:
if(box1 == null)
{
MessageBox.Show("Error 1");
}
if(box2 == null)
{
MessageBox.Show("Error 2");
}
if(box3 == null)
{
MessageBox.Show("Error 3");
}
If I am having 3 fields empty I will get message displayed 3 times one for each error. Is there a way to list all errors within one message box if error is true?
I was thinking of something like this:
bool a = true;
bool b = true;
bool c = true;
a = (box1 == null);
b = (box2 == null);
c = (box3 == null);
if(a || b || c)
{
//Display list of errors where condition is true
}
I would highly appreciate any suggestions.
Many thanks in advance.

Something like this:
var errors = new List<string>();
if(box1 == null)
errors.Add("Error 1");
if(box2 == null)
errors.Add("Error 2");
if(box3 == null)
errors.Add("Error 3");
if (errors.Count > 0)
MessageBox.Show(string.Join(Environment.NewLine, errors));

Use String builder for this String builder
private object box1;
private object box2;
private object box3;
//The following code base could be in a button click event
StringBuilder errorMessages = new StringBuilder();
if(box1 == null)
{
errorMessages.AppendLine("Error 1");
}
if(box2 == null)
{
errorMessages.AppendLine("Error 2");
}
if(box3 == null)
{
errorMessages.AppendLine("Error 3");
}
if(!string.IsNullOrWhiteSpace(Convert.ToString(errorMessages)))
{
MessageBox.Show(errorMessages.ToString(), "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}

Related

c# Getting error while try to read receiving email from gmail

Im trying to read receiving email from gmail and I did it.
If emails receive one by one it works perfectly.But if emails receive three or four at the same time.I miss at least two of them.
I hope describe my issue properly.
Here is my code for reading;
private void StartReceiving()
{
Task.Run(() =>
{
using (ImapClient client = new ImapClient("imap.gmail.com", 993, txtEmail.Text, txtSifre.Text, AuthMethod.Login, true))
{
if (client.Supports("IDLE") == false)
{
MessageBox.Show("server crash");
return;
}
client.NewMessage += new EventHandler<IdleMessageEventArgs>(OnNewMessage);
while (true) ;
}
});
}
static void OnNewMessage(object sender,IdleMessageEventArgs e)
{
//MessageBox.Show("mesaj geldi");
MailMessage m = e.Client.GetMessage(e.MessageUID, FetchOptions.Normal);
f.Invoke((MethodInvoker)delegate
{
f.txtGelen.AppendText("Body: " + m.Body + "\n");
});
}
What should I do ? Im kinda newbie at this,i have to read at least 4 emails at same time.
I never worked with gmail, but I had a similar problem when I was reading a TCP/IP log file, and it kept sending messages while I was processing.
The way I resolved it was to use a LIST of strings, and then process it in a background worker. Changing a string in place could be an issue in a race situation.
This is cut and pasted out of my code, and modified without checking my syntax, but it goes something like this:
private System.ComponentModel.BackgroundWorker backgroundWorkerReadMail;
private List<string> messagesToBeRead = null;
/****************************************************************
* readPassedMessage(string str)
* Puts message in queue, and calls background worker
****************************************************************/
private void readPassedMessage(string str)
{
string stringToRead = str;
if (messagesToBeRead == null) messagesToBeRead = new List<string>();
messagesToBeRead.Add(stringToRead);
if (backgroundWorkerReadMail != null && backgroundWorkerReadMail.IsBusy == false)
{
backgroundWorkerReadMail.RunWorkerAsync();
}
else if (backgroundWorkerReadMail == null)
{
// need to create it
}
}
private void backgroundWorkerReadMail_DoWork(object passedObj, DoWorkEventArgs e)
{
if (messagesToBeRead == null || messagesToBeRead.Count == 0) return;
if (backgroundWorkerReadMail.CancellationPending)
{
messagesToBeRead.Clear();
e.Cancel = true;
}
else
{
bool messagesLeftToRead = true;
while (messagesLeftToRead)
{
string curString = messagesToBeRead[0];
// < ADD CODE HERE TO DO WHATEVER YOU WANT WITH YOUR MESSAGE > //
messagesToBeRead.RemoveAt(0);
if (messagesToBeRead.Count == 0 || backgroundWorkerVoiceAssist.CancellationPending)
break;
} // while (messagesLeftToRead) end brace
}
}

Cannot access a disposed object but the program works

IN WPF project, whenever I try to add selected Student in selected university and display it on assoiated table.
Here is image of my table -
https://i.stack.imgur.com/KUHuF.png
I encounter this problem, once I hit update assosiated button.
public System.Data.Linq.Table<Student> Students
{
get
{
return this.GetTable<Student>();
}
}
The above code is in "Dataclasses1.designer.cs" window.
However, upon restarting the program, selected student is sucessfully added to selected university.
Here is my code -
private void UpdateAssociatedStudent_Click(object sender, RoutedEventArgs e)
{
if(ListUniversity.SelectedItem != null || ListStudent.SelectedItem != null)
{
using (dataContext = new DataClasses1DataContext())
{
UniversityManager universityManager = new UniversityManager
{
UniFK = int.Parse(ListUniversity.SelectedValue.ToString()),
StdFK = int.Parse(ListStudent.SelectedValue.ToString())
};
dataContext.UniversityManagers.InsertOnSubmit(universityManager);
dataContext.SubmitChanges();
}
ShowAssociatedStudents();
Sucess.Text = "Student is sucessfully added to University";
}
}
Edit - Adding image for error
https://i.stack.imgur.com/ApPxd.png
I think that you may need to change this line of code:
if(ListUniversity.SelectedItem != null || ListStudent.SelectedItem != null)
to
if(ListUniversity.SelectedItem != null && ListStudent.SelectedItem != null)
I've solved this issue by running try/catch instead of using 'Using' statement. my edited code looks like this.
//Add selected student from selected university in associated student listbox
private void UpdateAssociatedStudent_Click(object sender, RoutedEventArgs e)
{
if(ListUniversity.SelectedItem != null && ListStudent.SelectedItem != null)
{
try
{
uniManager = new UniversityManager()
{
UniFK = Convert.ToInt32(ListUniversity.SelectedValue),
StdFK = Convert.ToInt32(ListStudent.SelectedValue)
//UniFK = int.Parse(ListUniversity.SelectedItem.ToString()),
//StdFK = int.Parse(ListStudent.SelectedItem.ToString())
};
dataContext.UniversityManagers.InsertOnSubmit(uniManager);
dataContext.SubmitChanges();
ShowAssociatedStudents();
}
catch (FileNotFoundException)
{
Console.WriteLine("File Not Found.");
}
catch (OutOfMemoryException)
{
Console.WriteLine("Out of Memory.");
}
catch (IOException)
{
Console.WriteLine("An I/O error has occured.");
}
}
else
{
Failed.Text = "Please select the missing items from either university or student.";
}
}

Filter not changing on backspace press - radgridview - C#

In my program I have a text box and on text change a filter is applied to my RadGrid. However, on backspace the filter is not reapplied.
private void txt_search_TextChanged_1(object sender, EventArgs e)
{
try
{
CompositeFilterDescriptor searchFilter = new CompositeFilterDescriptor();
searchFilter.FilterDescriptors.Add(new FilterDescriptor("product", FilterOperator.Contains, txt_search.Text));
this.radGridView1.EnableFiltering = true;
this.radGridView1.MasterTemplate.Templates[0].EnableFiltering = true;
this.radGridView1.MasterTemplate.Templates[0].ShowFilteringRow = false;
this.radGridView1.MasterTemplate.ShowFilteringRow = false;
this.radGridView1.MasterTemplate.Templates[0].ShowTotals = true;
this.radGridView1.MasterTemplate.Templates[0].ShowFilterCellOperatorText = false;
if (txt_search.Text != "")
{
this.radGridView1.MasterTemplate.Templates[0].FilterDescriptors.Add(searchFilter);
}
foreach (GridViewRowInfo row in radGridView1.MasterTemplate.Rows)
{
if (row.ChildRows.Count == 0)
{
row.IsVisible = false;
}
else
{
row.IsVisible = true;
}
}
}
catch (Exception ex)
{
MessageBox.Show("Something went wrong searching the grid. Please try again and contact I.T. if this problem persists.", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
Is there another function which needs to be generated that is applied on backspace?
This code is taken from another program I have which is written in VB.net and converted. The filter works as it should in the VB version and is reapplied when text is removed etc.
Any help appreciated.

Iterate through all error provider messages, and display on clickEvent ?c# winform

I am creating a winform projects which utilities multiple error providers, I have unique errorproviders for each textBox. I'm trying to iterate through all of them and display all that are present in a messagebox.
So, I know I have to loop through my controls which I am doing correctly all my issue is that I cannot print out the specific textboxes which have errors. This is what I have, however the message Box statement is incorrect.
var errorProviders = new List<ErrorProvider>() {epPrefConTime, epPrefConNumber, epTitle, epEmail, epAlternative, epMobile, epTown, epLandline, epHouseName, epForeName, epSurname, epPostcode, epCountry, epHouseName, epLocality, epCounty };
foreach (Control c in panel1.Controls)
{
if (c is SpellBox)
{
if (errorProviders.Any(e => e.GetError(c).Length > 0))
{
MessageBox.Show(errorProviders.Any(e => e.GetError(c).ToString()));
return true;
}
}
else if (c is TextBox)
{
if (errorProviders.Any(e => e.GetError(c).Length > 0))
{
epCountry.SetError(btn_SaveDetails, "Errors present in form, please review!!!");
return false;
}
}
MessageBox.Show(e.GetError(c));
return true;
}
I'm Mapping my errorProviders in my my Validating events as follows for all 16 textBoxes:
private void txt_Forname_Validating(object sender, CancelEventArgs e)
{
if (util.useUnkownEntity(txt_Forname.Text))
{
UnkownEntity = true;
epForeName.SetError(txt_Forname, "Please use unknow entity!!");
return;
}
else if (string.IsNullOrWhiteSpace(txt_Forname.Text))
{
_IsValid = false;
return;
}
else if (util.IsAllLetters(txt_Forname.Text))
{
epForeName.Clear();
txt_Forname.Text = util.ToTitle(txt_Forname.Text);
_IsValid = true;
UseEntity = false;
return;
}
else
{
epForeName.SetError(txt_Forname, "InValid Forename, please reType!!"); _IsValid = false;
return;
}
}
If someone could help me ascertain how to message out all of my errors provider messages or even Which text boxes the errors are in

goto in c# and its usage

I have a subroutine. It comapares whether values are empty then doing something. For example, if they are empty, then warnings are raised.
The code works fine. But when value are not empty, the warnings are still pop out. Please help me to correct the logic.
Thanks.
private void btnNew_Click(object sender, EventArgs e)
{
try
{
if (txtbox1.Text.ToString().Trim() == string.Empty)
{
goto Msg1;
}
if (txtbox2.Text.ToString().Trim() == string.Empty)
{
goto Msg2;
}
DataRow dr = mydataSet.Tables[0].NewRow();
dr["Descript"] = txtbox1.Text;
dr["Abbr"] = txtbox2.Text;
dr["SortOrder"] = Convert.ToDecimal(numericOrder.Value);
if (SortOrders.Contains((decimal)dr["SortOrder"]))
{
goto Msg3;
}
mydataSet.Tables[0].Rows.Add(dr);
dgv.DataSource = mydataSet.Tables[0];
Msg1:
MessageBox.Show("Description is required.");
Msg2:
MessageBox.Show("Abbr is required.");
Msg3:
MessageBox.Show("Please select another one, this one is already used.");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
From the above code, you see. if txtbox1 has some value, the program still displays Msg1. I want to avoid it.
Because labels are just labels, and code after them is executed sequentially.
Why can't you do just this:
try
{
if (txtbox1.Text.ToString().Trim() == string.Empty)
{
MessageBox.Show("Description is required.");
return;
}
if (txtbox2.Text.ToString().Trim() == string.Empty)
{
MessageBox.Show("Abbr is required.");
return;
}
DataRow dr = mydataSet.Tables[0].NewRow();
dr["Descript"] = txtbox1.Text;
dr["Abbr"] = txtbox2.Text;
dr["SortOrder"] = Convert.ToDecimal(numericOrder.Value);
if (SortOrders.Contains((decimal)dr["SortOrder"]))
{
MessageBox.Show("Please select another one, this one is already used.");
return;
}
mydataSet.Tables[0].Rows.Add(dr);
dgv.DataSource = mydataSet.Tables[0];
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
It's so much more readable.
Restructure your code to avoid goto - it is a relic and not much use in a properly object oriented codebase.
Returning from the method, throwing exceptions or building an errors dictionary are all better options than using goto.
For example, you can have a List<string> errors which you add to when you get an error condition.
If it is empty, no errors were encountered, if it isn't, there were.
This is a good case were goto is the wrong way to go. Use something like this instead.
private void btnNew_Click(object sender, EventArgs e)
{
try
{
bool error = false;
if (txtbox1.Text.ToString().Trim() == string.Empty)
{
MessageBox.Show("Description is required.");
error = true;
}
if (txtbox2.Text.ToString().Trim() == string.Empty)
{
MessageBox.Show("Abbr is required.");
error = true;
}
if (SortOrders.Contains(Convert.ToDecimal(numericOrder.Value)
{
MessageBox.Show("Please select another one, this one is already used.");
error = true;
}
if(error)
return;
DataRow dr = mydataSet.Tables[0].NewRow();
dr["Descript"] = txtbox1.Text;
dr["Abbr"] = txtbox2.Text;
dr["SortOrder"] = Convert.ToDecimal(numericOrder.Value);
mydataSet.Tables[0].Rows.Add(dr);
dgv.DataSource = mydataSet.Tables[0];
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Edit
Just figured that my code didn't actually do the same as his first sample since it only displayed the first error no matter how many that occured. Updated my sample to accomodate for that.
I've always been taught to avoid goto like the plague, and it's something I've followed for years. I've never even considered it to be an option when writing code.
Thinking about it though, I did read an article a few years ago (which I can't find now) which said you could credibly use gotos only if you used it to jump down code, and not up: a rule that is stuck to here.
Check here for more info: Does anyone still use [goto] in C# and if so why?
There are better ways of using goto statement, for instacne using "return" (when used in the middle of a method), "break" and "continue". Have you ever used one of these?
private void btnNew_Click(object sender, EventArgs e)
{
try
{
var description = txtbox1.Text.Trim();
if (string.IsNullOrEmpty(description))
{
MessageBox.Show("Description is required.");
return;
}
var abbr = txtbox2.Text.Trim();
if (string.IsNullOrEmpty(abbr))
{
MessageBox.Show("Abbr is required.");
return;
}
var numericOrderValue = Convert.ToDecimal(numericOrder.Value);
if (SortOrders.Contains(numericOrderValue)
{
MessageBox.Show("Please select another one, this one is already used.");
return;
}
DataRow dr = mydataSet.Tables[0].NewRow();
dr["Descript"] = description;
dr["Abbr"] = abbr;
dr["SortOrder"] = numericOrderValue;
mydataSet.Tables[0].Rows.Add(dr);
dgv.DataSource = mydataSet.Tables[0];
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void btnNew_Click(object sender, EventArgs e)
{
try
{
if (txtbox1.Text.ToString().Trim() == string.Empty)
{
MessageBox.Show("Description is required.");
}
if (txtbox2.Text.ToString().Trim() == string.Empty)
{
MessageBox.Show("Abbr is required.");
}
DataRow dr = mydataSet.Tables[0].NewRow();
dr["Descript"] = txtbox1.Text;
dr["Abbr"] = txtbox2.Text;
dr["SortOrder"] = Convert.ToDecimal(numericOrder.Value);
if (SortOrders.Contains((decimal)dr["SortOrder"]))
{
MessageBox.Show("Please select another one, this one is already used.");
}
mydataSet.Tables[0].Rows.Add(dr);
dgv.DataSource = mydataSet.Tables[0];
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Try this. It works.

Categories

Resources