i recently got into coding i'm a first year IT student.
my prof give us a project where we should create any kind of management system and i pick the fast food type one.
i stumbled in some problem while making a checkout function.
I have this multiple picture boxes with individual check boxes i made a function that whenever the user clicked the picture box the checkbox will be checked.
my proj currently
the problem I'am having is i want to take all the data(text) of checked boxes with if statement but it would be so tedious because i have like 15 picture boxes with checkbox.
is there any simpler way to do this with for statement? or anything just to shorten my code.
this is my current code.
private void button1_Click(object sender, EventArgs e)
{
string food1 = "";
string food2 = "";
//...........................food15
if (checkBox1.Checked)
{
food1 = checkBox1.Text;
}
if (checkBox2.Checked)
{
food2 = checkBox2.Text;
}
//.............................................checkbox15
if (food1 != "" || food2 != "")
{
MessageBox.Show(food1 + food2);
}
else
{
MessageBox.Show("Pick something ");
}
}
something like this:
var foods = new List<string>();
foreach(var checkbox in Controls.OfType<CheckBox>())
{
if(checkbox.Checked)
{
foods.Add(c.Text);
}
}
if(foods.Count != 0){
//do popup
} else {
//pick something
}
the form provides a Form.Controls collection, which contains all controls on that form; OfType<CheckBox>() filters the list, so we're only looping though checkboxes.
i also used a list of foods rather than separate food1,food2 strings
you can then check the count, and use that.
also you could so something like String.Join(", ", foods.ToArray()); to make a comma separate list of your foods
Related
I have problem making my combobox searching inside the strings in the items.
I want to narrow down a list of members. They are formatted in this way (unique member id) - First name - last name.
When i leave all the settings "as is", then it will only "allow" me to search at the first char in the string.
The DataSource is set from a list, what are made from looping through all the files in a folder.
The code i have been using is as follows(partial code)
private void searchForShooterComboBox_KeyUp(object sender, KeyEventArgs e)
{
//if(e => KeyCode == Keys::Down || e => KeyCode == Keys::Down)
//string comboBoxValue = searchForShooterComboBox.Text;
//searchForShooterComboBox.DataSource = null;
//searchForShooterComboBox.DataSource = fliterComboBox(searchForShooterComboBox, memberFileNames);
//searchForShooterComboBox.Text = comboBoxValue;
}
private void searchForShooterComboBox_TextChanged(object sender, EventArgs e)
{
searchForShooterComboBox.DataSource = null;
searchForShooterComboBox.DataSource = fliterComboBox(searchForShooterComboBox, memberFileNames);
}
private List<string> fliterComboBox(ComboBox cobx, List<string> stringList)
{
List<string> returnList = new List<string>();
if (cobx.Text != ""){
try
{
foreach (string s in stringList)
{
if (s.Contains(cobx.Text))
{
returnList.Add(s);
}
}
}catch{
}
}
return returnList;
}
some of the code i tried seemed to filter the list OK, but after the methods ran it fills what seems to be the first item in the new list into the "text field", so the user wont be able to continue typing a name ex.
Will it make any difference using ComboBox.Items.Add() and ComboBox.Items.Remove() instead of using DataSource?
edit: the comboBox DataSource is initially set in the form_load event handler. Where the following code regarding the combobox is:
searchForShooterComboBox.DropDownStyle = ComboBoxStyle.DropDown;
searchForShooterComboBox.AutoCompleteMode = AutoCompleteMode.Suggest;
searchForShooterComboBox.AutoCompleteSource = AutoCompleteSource.ListItems
Thanks for taking the time to look.
Okay seems i figured something out myself,don't know if its the best way, but seems to get the job done :)
firstly i added the string's into both the ComboBox.items and into a list<string>. The reason for adding them both ways is for the user to see all available options on load.
for (int i = 0; i < membersFiles.Length; i++)
{
searchForShooterComboBox.Items.Add(membersFiles[i].Replace(".txt", "").Replace(#"C:\Users\Nicolai\Desktop\skytter\", "").Replace("-", " "));
memberFileNames.Add(membersFiles[i].Replace(".txt", "").Replace(#"C:\Users\Nicolai\Desktop\skytter\", "").Replace("-", " "));
}
After that i added a combobox_keydown event from the property window.
private void searchForShooterComboBox_KeyDown(object sender, KeyEventArgs e)
{
try
{
//checking if the key pressed is RETURN, in that case try to fill the combobox with the selected item,
//and continuing with other method
if (e.KeyValue == 13)
{
searchForShooterComboBox.Text = (string)searchForShooterComboBox.SelectedItem;
fillInfoInForm();
}
//making sure the key pressed IS NOT DOWN, UP, LEFT, RIGHT arrow key.
else if (e.KeyValue > 40 || e.KeyValue < 37)
{
filterComboBox(searchForShooterComboBox, searchForShooterComboBox.Text);
searchForShooterComboBox.Select(searchForShooterComboBox.Text.Length, 0);
searchForShooterComboBox.DroppedDown = true;
}
}
catch (FileNotFoundException ex) {
MessageBox.Show("Der blev ikke fundet nogen fil med flg. sti " + ex.FileName + "\nHusk at vælge hele navnet i listen, eller skriv det nøjagtigt som det står!");
}
}
made this method to search through the list items, clear the items in the combobox, and add the ones that match.
private void filterComboBox(ComboBox cobx, string enteredSearch)
{
//clearing ComboBox items before adding the items from the LIST that meets the search
cobx.Items.Clear();
//looping over the items from the list, comparing them to the search from the combobox text field.
//if the item in the list does not contain the string searched it will return an index of -1.
for (int i = memberFileNames.Count-1; i >= 0; i--)
{
if (memberFileNames[i].IndexOf(enteredSearch, 0, StringComparison.CurrentCultureIgnoreCase) >= 0)
{
cobx.Items.Add(memberFileNames[i]);
}
}
}
if you are having trouble finding the right KeyValues, try looking at
https://msdn.microsoft.com/en-us/library/system.windows.forms.keyeventargs.keyvalue(v=vs.110).aspx
and copy paste the code from there, and add it to you key_down event handler, and it will show most info(if not all) in a message box.
That was my workaround, if you have a better way of doing it, i am all ears :)
I have a DataGridView that I populate with a file and folder list. I'd like to sort the DataGridView alphabetically, but with all the folders above the files. Here's the general idea:
.\folder1\
.\folder2\
.\folder3\
.\file1
.\file2
I have a column with icons for the different filetypes, so there's a folder icon and file icons. It's the only difference I have between the two columns. Here's a picture:
So you can see that files and folders have different icons. Here is my current sort method:
private void dgvFiles_SortCompare(object sender, DataGridViewSortCompareEventArgs e) {
if(e.Column.Index == 1) {
// ???
}
else if(e.Column.Index == 4) {
string cellValue1 = e.CellValue1.ToString(),
cellValue2 = e.CellValue2.ToString();
if(!string.IsNullOrWhiteSpace(cellValue1) && !string.IsNullOrWhiteSpace(cellValue2)) {
cellValue1 = Regex.Replace(cellValue1, "[^.0-9]", "");
cellValue2 = Regex.Replace(cellValue2, "[^.0-9]", "");
int a = int.Parse(cellValue1), b = int.Parse(cellValue2);
e.SortResult = a.CompareTo(b);
e.Handled = true;
}
}
}
Is it possible to sort the DataGridView this way using a custom SortCompare method? If so, how?
I depends on how you've set the image inside the column but instead of using e.CellValue1 and e.CellValue2 as you have done for the size sorting, use GridName.Rows[e.RowIndex1] and GridName.Rows[e.RowIndex2] to access the underlying data instead.
So what I did instead was I created a class for folder items named FolderItem. I then created a list of these FolderItem objects and populated the DataGridView using the list. It actually made it really easy--I just had to use this snippet of code:
List<FolderItem> items = new List<FolderItem>();
private void dgvFiles_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) {
if(e.ColumnIndex == 1) {
items.OrderBy(i => i.type).ThenBy(i => i.oldName);
items.Reverse(); // to account for ascending/descending order
RefreshDataGridView();
}
}
public void RefreshDataGridView() {
dgvFiles.Rows.Clear();
foreach(FolderItem item in items) {
dgvFiles.Rows.Add(item.icon, item.oldName, item.newName, item.type, item.size, item.created, item.modified);
}
}
(type was null for folders so it occurred above the other items.)
You could also probably find some way to bind the datagridview to the list, but I didn't do that.
I've been working on the past couple of days on a ListView based Music player using NAudio in C#. It's now time for me to start working on the forward/previous functions but I've come to a bit of a bump in the road. I need to select whatever the next item in the listView I have is. However, it is not selected by the user but instead is marked as now playing by a checkmark next to it with the default ListView checkboxes.
Here's what it looks like:
I've got a public string that's accessible by anything; it has the filename of the currently playing track in it. Whenever I click to play a track, I've got a foreach loop that loops through all of the items in this listView (I've got a second listview in another tab that has all the music I click to play from) and if the filename subitem and currentlyPlaying string match, then it checks it. If not, it unchecks.
I've got an event handler in my mainclass for when the playback stops on the track. What's going to go in there will be the logic for the next track. I've got a general idea of what to do but I'm not sure how to go about doing it
Get the index of the item with the check mark next to it
Get the item after it
Retrieve its fileName subitem
Play it
So what would be the way to go about doing this? I'm still a bit confused with listViews and such.
Update: Also, how possible is it to disable the user checking the check box, I've got it down for when it's a double click but what about when the user checks the checkbox themselves?
Update 2: Here's the eventhandler with some scratch code I was working on
public void waveOutDevice_PlaybackStopped(object sender, StoppedEventArgs e)
{
string fileName;
foreach (ListViewItem lvi in playListView.Items)
{
fileName = lvi.SubItems[1].Text;
if(lvi.Checked == true)
{
int finIndex;
lvi.Checked = false;
finIndex = lvi.Index;
//finIndex + 1;
}
}
}
I think you are just about there. all you need to do is something like this:
public void waveOutDevice_PlaybackStopped(object sender, StoppedEventArgs e)
{
string fileName;
foreach (ListViewItem lvi in playListView.Items)
{
fileName = lvi.SubItems[1].Text;
if(lvi.Checked == true)
{
int finIndex;
lvi.Checked = false;
finIndex = lvi.Index;
finIndex++;
if(finIndex < playListView.Count())
{
var nextGuy = playListView.Items[finIndex];
nextGuy.Checked = true;
//Play the file and what not.
}
}
}
}
I have a BindingList< KeyValuePair < string, string > > that is bound to a ComboBox control. Based on some conditions, the BindingList will be added a new KeyValuePair. Now, the Newly added item shows up at index 0 of the Combobox, instead of at the end.
While debugging, I found that the BindingList has got the right order. (i.e, the new KeyValuePair is appended)
Also, I check the SelectedValue of the ComboBox in it's SelectedIndexChanged handler and it seems to be not of the ListItem that got selected. Instead, it is that of the supposed ListItem, if the ComboBox had got the right order as in its DataSource, - the BindingList..
The code is a small part of a large project.. Plz let me know if the question is not clear. I can put the relevant parts of the code as per our context.
How could something like this happen? What can I do differently?
I have this class something like this.
public class DropdownEntity
{
//removed all except one members and properties
private string frontEndName
public string FrontEndName
{
get {return this.frontEndName; }
set {this.frontEndName= value; }
}
//One Constructor
public DropdownEntity(string _frontEndName)
{
this.FrontEndName = _frontEndName;
//Removed code which initializes several members...
}
//All methods removed..
public override string ToString()
{
return frontEndName;
}
}
In my windows form, I have a tab control with several tabs. In one of the tabs pages, I have a DataGridView. The user is supposed to edit the cells and click on a Next - button. Then, some processing will be done, and the TabControl will be navigated to the next tab page.
The next tab page has the combobox that has the problem I mentioned. This page also has a back button, which will take back.. the user can modify the gridview cells again.. and click on the next button. This is when the order gets messed up.
I am posting here the Click event handler of the Next Button.. Along with the class, with the rest of the code removed.
public partial class AddUpdateWizard : Form
{
//Removed all members..
BindingList<KeyValuePair<string, string>> DropdownsCollection;
Dictionary<string, DropdownEntity> DropdownsDict;
//Defined in a partial definition of the class..
DataGridView SPInsertGridView = new DataGridView();
ComboBox DropdownsCmbBox = new ComboBox();
Button NextBtn2 = new Button();
Button BackBtn3 = new Button();
//Of course these controls are added to one of the panels
public AddUpdateWizard(MainForm mainForm)
{
InitializeComponent();
DropdownsDict = new Dictionary<string, DropdownEntity>();
}
private void NextBtn2_Click(object sender, EventArgs e)
{
string sqlArgName;
string frontEndName;
string fieldType;
for (int i = 0; i < SPInsertGridView.Rows.Count; i++)
{
sqlArgName = "";
frontEndName = "";
fieldType = "";
sqlArgName = SPInsertGridView.Rows[i].Cells["InsertArgName"].Value.ToString().Trim();
if (SPInsertGridView.Rows[i].Cells["InsertArgFrontEndName"].Value != null)
{
frontEndName = SPInsertGridView.Rows[i].Cells["InsertArgFrontEndName"].Value.ToString().Trim();
}
if (SPInsertGridView.Rows[i].Cells["InsertArgFieldType"].Value != null)
{
fieldType = SPInsertGridView.Rows[i].Cells["InsertArgFieldType"].Value.ToString().Trim();
}
//I could have used an enum here, but this is better.. for many reasons.
if (fieldType == "DROPDOWN")
{
if (!DropdownsDict.ContainsKey(sqlArgName))
DropdownsDict.Add(sqlArgName, new DropdownEntity(frontEndName));
else
DropdownsDict[sqlArgName].FrontEndName = frontEndName;
}
else
{
if (fieldType == "NONE")
nonFieldCount++;
if (DropdownsDict.ContainsKey(sqlArgName))
{
DropdownsDict.Remove(sqlArgName);
}
}
}
//DropdownsCollection is a BindingList<KeyValuePair<string, string>>.
//key in the BindingList KeyValuePair will be that of the dictionary.
//The value will be from the ToString() function of the object in the Dictionary.
DropdownsCollection = new BindingList<KeyValuePair<string,string>>(DropdownsDict.Select(kvp => new KeyValuePair<string, string>(kvp.Key, kvp.Value.ToString())).ToList());
DropdownsCmbBox.DataSource = DropdownsCollection;
DropdownsCmbBox.DisplayMember = "Value";
DropdownsCmbBox.ValueMember = "Key";
//Go to the next tab
hiddenVirtualTabs1.SelectedIndex++;
}
private void BackBtn3_Click(object sender, EventArgs e)
{
hiddenVirtualTabs1.SelectedIndex--;
}
//On Selected Index Changed of the mentioned Combobox..
private void DropdownsCmbBox_SelectedIndexChanged(object sender, EventArgs e)
{
if (DropdownsCmbBox.SelectedValue != null)
{
if (DropdownsDict.ContainsKey((DropdownsCmbBox.SelectedValue.ToString())))
{
var dropdownEntity = DropdownsDict[DropdownsCmbBox.SelectedValue.ToString()];
DropdownEntityGB.Text = "Populate Dropdowns - " + dropdownEntity.ToString();
//Rest of the code here..
//I see that the Datasource of this ComboBox has got the items in the right order.
// The Combobox's SelectedValue is not that of the selected item. Very Strange behavior!!
}
}
}
}
The very first time the user clicks the Next Button, it's fine. But if he clicks the Back Button again and changes the Data Grid View cells.. The order will be gone.
I know, it can be frustrating to look at. It's a huge thing to ask for help. Any help would be greatly appreciated!
Please let me know if you need elaboration at any part.
Thanks a lot :)
I think you have two problems here.
First, if you want to retain the order of the items you should use an OrderedDictionary instead of a regular one. A normal collection will not retain the order of the items when you use Remove method. You can see more info about this related to List here.
You could use such dictionary like this:
DropDownDict = new OrderedDictionary();
// Add method will work as expected (as you have it now)
// Below you have to cast it before using Select
DropDownCollection = new BindingList<KeyValuePair<string, string>>(DropDownDict.Cast<DictionaryEntry>().Select(kvp => new KeyValuePair<string, string>(kvp.Key.ToString(), kvp.Value.ToString())).ToList());
The second problem could be that you change the display name (FrontEndName) of already existing items, but the key is preserved. When you add a new item, try to remove the old one that you're not using anymore and add a new item.
The Sorted Property of the Combobox is set to True! I didn't check that until now. I messed up. Terribly sorry for wasting your time Adrian. Thanks a lot for putting up with my mess here.. :)
I have a rather simple problem (I bealive). I have this method:
void appointments_SearchCompleted(object sender, AppointmentsSearchEventArgs e)
{
if (e.Results.Count() == 0)
{
results = "no events for the selected day";
//MessageBox.Show(results);
}
else
{
results = e.Results.Count() + " events found";
sourceItem = e.Results;
//MessageBox.Show(results);
}
}
And I can't "save" both results and sourceItem variables(which are class fields).
The Message box inside this method shows everything correct, howerver, on the outside results reverts to the default value.
The answer is simple: I didn't get how ansynch download works.
In my case I had to create a reference to my MainPage class, and bind items in appointments_SearchCompleted method.
Simple as that.