I have a dialog that is used to select which forms to show. Originally it was just being selected from a combo box, but now we need to select multiple, so we changed it to a list box.
Here is the method that we used for the combo box:
if (view.ShowDialog() == DialogResult.OK)
{
if (view.FormType == "Form1")
return new Form1_Controller();
else if (view.FormType == "Form2")
return new Form2_Controller();
else if (view.FormType == "Form3")
return new Form3_Controller();
else return null;
}
else
{
return null;
}
How can we encapsulate this in a loop that will return a controller for each selection?
For example, I have tried something like
foreach (ListBoxItem listItem in view.ListBox1)
{
//do if (view.FormType == "Form1")
}
But I don't know the right syntax to use.
To open all forms simultaneously, I would try a different approach something like this
ArrayList controllersSelected = new ArrayList();
foreach (var item in view.ListBox1.SelectedItems)
GetSelectedItem(item.Value, out controllersSelected);
//Your logic to display selected forms simultaneously
DisplaySimultaneousForms(controllersSelected);
private void GetSelectedItem(formName, out ArrayList list)
{
if (view.FormType == "Form1")
list.Add(new Form1_Controller());
else if (view.FormType == "Form2")
list.Add(new Form2_Controller());
else if (view.FormType == "Form3")
list.Add(new Form3_Controller());
}
use SelectedItems:
foreach (var item view.ListBox1.SelectedItems)
SelectForm(item.ToString());
void SelectForm(string value)
{
if(value == "Form1")
return new Form1_Controller();
...
}
You can use below code :
foreach (var item in view.ListBox1.SelectedItems)
{
ShowForm(item.Value);
}
private void ShowForm(formName)
{
if (view.FormType == "Form1")
return new Form1_Controller();
else if (view.FormType == "Form2")
return new Form2_Controller();
else if (view.FormType == "Form3")
return new Form3_Controller();
else return null;
}
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i <= listBox1.SelectedItems.Count - 1; i++)
{
switch (listBox1 .Items [i].ToString ())
{
case "FirstForm":
Form2 frm2 = new Form2();
frm2.Show();
break;
case "SecondForm":
Form3 frm3 = new Form3();
frm3.Show();
break;
default:
break;
}
}
}
Related
So I have a fitler TextBox where I want to search for different type of docs in a grid the code where I have different type of columns such as: Date,DocId,ClientId.
For a search I write on a filter Textbox something like that DocId:2002 and It just work fine but when I try to make a multiple search for example DocId:2002 ClientId:201 It doesnt search because of the return it just does an infinite loop.
private void TextBoxFilter_TextChanged(object sender, TextChangedEventArgs e)
{
foreach (Match m in Regex.Matches((sender as TextBox).Text, pattern, options))
{
if (m.Value != "")
{
Func<String, String> untilSlash = (s) => { return filters[re.Match(s).Groups[1].ToString()] = re.Match(s).Groups[2].ToString(); };
untilSlash(m.Value);
}
}
ICollectionView cv = CollectionViewSource.GetDefaultView(this.DataGridDocList.ItemsSource);
if (filters.Count == 0)
{
cv.Filter = null;
}
else
{
cv.Filter = o =>
{
for (int i = 0; i < filters.Count; i++)
{
if (filters.ElementAt(i).Key == "Date")
{
if (DateVerify.Match(filters.ElementAt(i).Value).Success)
{
return (o as Document).DateCreated < Convert.ToDateTime(DateVerify.Match(filters.ElementAt(i).Value).Groups[1].ToString()) && (o as Document).DateCreated > Convert.ToDateTime(DateVerify.Match(filters.ElementAt(i).Value).Groups[2].ToString());
}
else
{
var dateString = (o as Document).DateCreated.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture);
return dateString.Contains(DateVerify.Match(filters.ElementAt(i).Value).Groups[1].ToString());
}
}
if (filters.ElementAt(i).Key == "DocId")
{
return (o as Document).DocumentId.ToString().Contains(filters.ElementAt(i).Value);
}
if (filters.ElementAt(i).Key == "ClientId")
{
return (o as Document).ClientId.ToUpper().Contains(filters.ElementAt(i).Value.ToUpper());
}
}
return false;
};
filters.Clear();
}
}
So my question is how can I do an big search with all the filters at one time?
Manually I can add them 1 by 1 and it will be something like search1 && search2 && search3 but It will take too much time and It's probably not the best solution
There are many ways of building up the predicate. However my suggestion is to keep it simple and just create one method that returns true or false. It's good practice to only return once in a method.
The code below if for illustration purposes (as I'm unable to test it):
ICollectionView cv = CollectionViewSource.GetDefaultView(this.DataGridDocList.ItemsSource);
if (filters.Any())
{
cv.Filter = new Predicate<object>(PredicateFilter);
}
else
{
cv.Filter = null;
}
Then Predicate method to filter results:
public bool PredicateFilter(object docObj)
{
Document doc = docObj as Document;
var response = new List<bool>();
for (int i = 0; i < filters.Count; i++)
{
if (filters.ElementAt(i).Key == "Date")
{
if (DateVerify.Match(filters.ElementAt(i).Value).Success)
{
response.Add(doc.DateCreated < Convert.ToDateTime(DateVerify.Match(filters.ElementAt(i).Value).Groups[1].ToString()) && doc.DateCreated > Convert.ToDateTime(DateVerify.Match(filters.ElementAt(i).Value).Groups[2].ToString()));
}
else
{
var dateString = doc.DateCreated.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture);
response.Add(dateString.Contains(DateVerify.Match(filters.ElementAt(i).Value).Groups[1].ToString()));
}
}
else if (filters.ElementAt(i).Key == "DocId")
{
response.Add(doc.DocumentId.ToString().Contains(filters.ElementAt(i).Value));
}
else if (filters.ElementAt(i).Key == "ClientId")
{
response.Add(doc.ClientId.ToUpper().Contains(filters.ElementAt(i).Value.ToUpper()));
}
}
return response.All(m => m); // if all filters came back with true, return 1 response of true else false.
}
newbie in learning c# here, im calculating cgpa and when user pick the number of subject they take, accordingly, the textBox will Enabled true according to the number of user subject and the rest is Enabled false. So when im clicking calculateCGPA, i want to popup message if the user input is empty but messageBox is shown x number of time according to the number that user left empty. How to get it to show only once. Tqvm in advanced. Explanation is very much appreciated.
1.CheckingUserCheckedRadioButton
private void DisplayTextBox(Control con)
{
foreach (Control c in con.Controls)
{
if (rad1.Checked)
{
if (c is TextBox)
{
((TextBox)c).Enabled = false;
txtCCode1.Enabled = true;
txtGrade1.Enabled = true;
}
else
{
DisplayTextBox(c);
}
}
}
}
2.DisplayingMessageBoxWhenClickingCalculate
private void calculate(Control con)
{
foreach (Control c in con.Controls)
{
if (c is TextBox)
{
if (c.Text == "")
{
DialogResult x = new DialogResult();
x = MessageBox.Show("TextBox cannot be Empty");
if (x == DialogResult.OK)
txtCCode1.Focus();
}
else
{
int totalCredHours = 0;
CalcTotalCredHours(credHour1, credHour2, credHour3, credHour4, credHour5, credHour6, ref totalCredHours);
courseGP1 = CalcCourseGradePoint(credHour1, gradePoint1);
courseGP2 = CalcCourseGradePoint(credHour2, gradePoint2);
courseGP3 = CalcCourseGradePoint(credHour3, gradePoint3);
courseGP4 = CalcCourseGradePoint(credHour4, gradePoint4);
courseGP5 = CalcCourseGradePoint(credHour5, gradePoint5);
courseGP6 = CalcCourseGradePoint(credHour6, gradePoint6);
double totalCGP = CalcTotalCGP(courseGP1, courseGP2, courseGP3, courseGP4, courseGP5, courseGP6);
double gpa = CalcGPA(totalCGP, totalCredHours);
lblGPA.Text = gpa.ToString("N");
}
}
else
{
calculate(c);
}
}
}
Create a method that shows the message box with a global flag:
bool showed = false;
private ShowMessageBox(string message)
{
if (!showed)
MessageBox.Show(message);
showed = true;
}
In you code call this method
ShowMessageBox("TextBox cannot be Empty")
instead of
MessageBox.Shows("TextBox cannot be Empty")
You should have following lines:
static bool showed = false; // <---- This line
private void DisplayTextBox(Control con)
{
if (rad1.Checked)
{
foreach (Control c in con.Controls)
{
if (c is TextBox)
{
((TextBox)c).Enabled = false;
txtCCode1.Enabled = true;
txtGrade1.Enabled = true;
}
else
{
DisplayTextBox(c);
}
}
}
showed = false; // <---- This line
}
private void calculate(Control con)
{
foreach (Control c in con.Controls)
{
if (c is TextBox)
{
if (c.Text == "")
{
if (!showed) // <---- This line
{ // <---- This line
showed = true; // <---- This line
DialogResult x = new DialogResult();
x = MessageBox.Show("TextBox cannot be Empty");
if (x == DialogResult.OK)
txtCCode1.Focus();
} // <---- This line
}
else
{
int totalCredHours = 0;
CalcTotalCredHours(credHour1, credHour2, credHour3, credHour4, credHour5, credHour6, ref totalCredHours);
courseGP1 = CalcCourseGradePoint(credHour1, gradePoint1);
courseGP2 = CalcCourseGradePoint(credHour2, gradePoint2);
courseGP3 = CalcCourseGradePoint(credHour3, gradePoint3);
courseGP4 = CalcCourseGradePoint(credHour4, gradePoint4);
courseGP5 = CalcCourseGradePoint(credHour5, gradePoint5);
courseGP6 = CalcCourseGradePoint(credHour6, gradePoint6);
double totalCGP = CalcTotalCGP(courseGP1, courseGP2, courseGP3, courseGP4, courseGP5, courseGP6);
double gpa = CalcGPA(totalCGP, totalCredHours);
lblGPA.Text = gpa.ToString("N");
}
}
else
{
calculate(c);
}
}
}
I you don't want to reshuffle your code much , the best way is to add a break statement if any of the textboxes is Empty.
For e.g
foreach (Control c in con.Controls)
{
if (c is TextBox)
{
if (c.Text == "")
{
DialogResult x = new DialogResult();
x = MessageBox.Show("TextBox cannot be Empty");
if (x == DialogResult.OK)
txtCCode1.Focus();
break;
}
Is there a better way to pass this through the addClick (ideally I don't want this at all and I would want it to auto-pass through)?
public void addClick(object sender, EventArgs e)
{
if ((string) HttpContext.Current.Session["whichMenu"] == "systemDateFormats")
{
WorldViewNet.system.DateFormats dateformats = new WorldViewNet.system.DateFormats();
dateformats.addClick();
}
else if ((string) HttpContext.Current.Session["whichMenu"] == "programmingLabels")
{
WorldViewNet.programming.Labels labels = new WorldViewNet.programming.Labels();
labels.addClick();
}
else if ((string) HttpContext.Current.Session["whichMenu"] == "programmingPLUSearch")
{
WorldViewNet.programming.PLUSearch pluSearch = new WorldViewNet.programming.PLUSearch();
pluSearch.addClick();
}
else if ((string) HttpContext.Current.Session["whichMenu"] == "programmingServings")
{
WorldViewNet.programming.Servings servings = new WorldViewNet.programming.Servings();
servings.addClick();
}
else if ((string) HttpContext.Current.Session["whichMenu"] == "programmingShops")
{
WorldViewNet.programming.Shops shops = new WorldViewNet.programming.Shops();
shops.addClick();
}
else if ((string) HttpContext.Current.Session["whichMenu"] == "programmingTextsSearch")
{
WorldViewNet.programming.TextsSearch textsSearch = new WorldViewNet.programming.TextsSearch();
textsSearch.addClick();
}
else if ((string) HttpContext.Current.Session["whichMenu"] == "systemTemplates")
{
WorldViewNet.system.Templates templates = new WorldViewNet.system.Templates();
templates.addClick();
}
}
If anyone has any suggestions, that would help me out I would be grateful.
I thing below models maybe good for your codes:
public void addClick(object sender, EventArgs e)
{
object control;
string opt = (string) HttpContext.Current.Session["whichMenu"];
switch (opt)
{
case "systemDateFormats": control = new WorldViewNet.system.DateFormats();
break;
case "programmingLabels": control = new WorldViewNet.programming.Labels();
break;
case "programmingPLUSearch": control = new WorldViewNet.programming.PLUSearch();
break;
case "programmingServings": control = new WorldViewNet.programming.Servings();
break;
case "programmingShops": control = new WorldViewNet.programming.Shops();
break;
case "programmingTextsSearch": control = new WorldViewNet.programming.TextsSearch();
break;
case "systemTemplates": control = new WorldViewNet.system.Templates();
break;
default: new WorldViewNet.system.DefaultType();
}
((dynamic)control).addClick();
}
I have a textbox in my form for user to key in an item code.
When the focus of the textbox is lost, it will look into the database to check if the item code exists or not.
However, I am getting infinite loop when I try to lose focus by clicking on other textboxes.
private void txtICode_LostFocus(object sender, RoutedEventArgs e)
{
if (txtICode.IsFocused != true)
{
if (NewData)
{
if (txtICode.Text != null)
{
if (txtICode.Text != "")
{
Item temp = new Item();
Item[] list = temp.Query(new object[] { Item.DataEnum.Item_Code }, new string[] { txtICode.Text });
if (list.Length > 0)
{
System.Windows.Forms.MessageBox.Show("This item code is already being used.", "Invalid information");
txtICode.Focus();
return;
}
}
}
}
}
}
The txtICode.IsFocused is set to true every time after the end of the method and the loop just continues forever.
I tried removing txtICode.Focus(); but it makes no difference.
Is there anything wrong with my code?
I am using .Net 3.5 and WPF for my form.
You do not have to restore focus to TextBox in the LostFocus event.
remove these 2 lines :
txtICode.Focus();
return;
You could implement code more clean & readable way :
private void txtICode_LostFocus(object sender, RoutedEventArgs e)
{
if (!NewData)
return;
if (String.IsNullOrEmpty(txtICode.Text))
return;
Item temp = new Item();
Item[] list = temp.Query(new object[] { Item.DataEnum.Item_Code }, new string[] { txtICode.Text });
if (list.Length > 0)
{
System.Windows.Forms.MessageBox.Show("This item code is already being used.", "Invalid information");
}
}
private void txtICode_LostFocus(object sender, RoutedEventArgs e)
{
string inputText = txtICode.Text;
if (string.IsNullOrEmpty(inputText) || !NewData)
{
return;
}
Item temp = new Item();
Item[] list = temp.Query(new object[] { Item.DataEnum.Item_Code },
new string[] { inputText });
if (list != null && list.Length > 0)
{
MessageBox.Show("This item code is already being used.", "Invalidinformation");
txtICode.Focus();
return;
}
}
You can use BeginInvoke Method to execute asynchronously:
private void txtICode_LostFocus(object sender, RoutedEventArgs e)
{
txtICode.Dispatcher.BeginInvoke(() => {
if (txtICode.IsFocused != true)
{
if (NewData)
{
if (txtICode.Text != null)
{
if (txtICode.Text != "")
{
Item temp = new Item();
Item[] list = temp.Query(new object[] { Item.DataEnum.Item_Code }, new string[] { txtICode.Text });
if (list.Length > 0)
{
System.Windows.Forms.MessageBox.Show("This item code is already being used.", "Invalid information");
txtICode.Focus();
return;
}
}
}
}
});
}
I'm having troubles finding a string into a listbox, my string NombreCompleto is made of 3 strings that I previously had read from a file(ESSD), after I had recovered this string, I want to know if this string is in my listbox3, I tried several methods but it doesnt seem to work.
Here is my code.
foreach (string h in Directory.EnumerateFiles(NomDirec, "resume*"))
{
this.listBox1.Items.Add(h);
var NombreLinea = File.ReadLines(h);
foreach (string item in NombreLinea)
{
NombreAbuscar.Add(item.Remove(item.IndexOf(':')));
this.listBox3.Items.Add(item.Remove(item.IndexOf(':')));
}
foreach (string t in Directory.EnumerateFiles(NomDirec, "ESSD1*"))
{
string[] Nombre = File.ReadLines(t).ElementAtOrDefault(6).Split(':');
string[] ApellidoPat = File.ReadLines(t).ElementAtOrDefault(7).Split(':');
string[] ApellidoMat = File.ReadLines(t).ElementAtOrDefault(8).Split(':');
string NombreCompleto = ApellidoPat[1]+" "+ ApellidoMat[1] +","+" "+ Nombre[1];
string Nom2 = NombreCompleto.ToString();
int index = listBox3.FindString(Nom2);
if (index != -1)
{
this.listBox1.Items.Add(t);
MessageBox.Show("Find It");
}
else { MessageBox.Show("Not Found :#"); }
}
You can try with this code - based on Linq operator Where, ...
var selectedItems = from li in listBox3.Items
where li.Text == Nom2
select li.Text;
if(selectedItems.Any())
....
Try this out:
int index = -1;
for (int i = 0; i < listBox3.Items.Count; ++i)
if (listBox3.Items[i].Text == Nom2) { index = i; break; }
if (index != -1)
{
this.listBox1.Items.Add(t);
MessageBox.Show("Find It");
}
else { MessageBox.Show("Not Found :#");
Really easy way to find if a certain string is in a listbox.
private void btnAddRecipe_Click(object sender, EventArgs e)
{
bool DoesItemExist = false;
string searchString = txtRecipeName.Text;
int index = lstRecipes.FindStringExact(searchString, -1);
if (index != -1) DoesItemExist = true;
else DoesItemExist = false;
if (DoesItemExist)
{
//do something
}
else
{
MessageBox.Show("Not found", "Message", MessageBoxButtons.RetryCancel, MessageBoxIcon.Stop);
}
PopulateRecipe();
}