In my program, I want to put user-entered data into a category, based on what they selected in the COMBOBOX.
There are four categories, and four DATAGRIDVIEWS that are within a TABCONTROL (on a separate form).
I'm able to add the information a user entered, but the COMBOBOX doesn't have it's functionality yet.
How do I make it so that if the user selects "category 1", it sends the data they entered into dataGridView1, "category 2" to dataGridView2?
I know this will require "if, else-if" statement, but I'm not sure as to how to direct the data based on the COMBOBOX selection to the appropriate DGV.
I would make the ComboBox a required field on the entry form. When the user submits the entry, it should be routed to the proper category. Use the ComboBox.SelectedIndex (or .SelectedText or .SelectedValue) to determine which category was selected. The ComboBox.DropDownStyle should probably be DropDownList so the user has to select from the listed options.
If the categorization happens after the entry, then you should have an Apply or Categorize button that performs the actual categorization. The logic is pretty simple:
private void CategorizeButton_Click(object sender, EventArgs e)
{
switch (CategoryComboBox.SelectedIndex)
{
case 0: // Category 1
// Code to send to Category 1
break;
case 1: // Category 2, repeat as necessary
// Code to send to Category 2
break;
default:
MessageBox.Show("Please select a category!");
CategoryComboBox.Focus();
return;
}
}
This can be refactored and simplified if the code to send to the categories is almost identical. Then you can use the SelectedIndex to identify the target DataGridView instead and reduce the code length and repitition.
Would this be a better or valid way to do it:
if(combobox1.SelectedValue = "category1"){
//user-entered info goes to DGV1
else if(combobox1.SelectedValue = "category2")
//user-entered info goes to DGV2
//.etc.
Related
I have a Listbox that allows you to select different menus. Say my Listbox contains 3 indexes. 1, 2, and 3. Index 3 is special and does things that effect 1 and 2. I want to do a specific action if the selected index changes from 3 to any other index.
Basically I want the following.
if (selectedindex was = 3)
{
//Do stuff
}
Edit: I wanted to clarify a little bit. My listbox contains 3 things you can select, see below. Bare in mind that the numbers are used for my example.
So, if I click on 3, then click on 1 or 2, I want it to do a very specific thing.
Create a class variable to hold the previously selected value for the list. When the form gets created, set the selected item for the list and initialize the previously selected value. Add a changed event handler to the list and use it to maintain the previously selected value. Use the previously selected value to react as appropriate for your problem - in this case whenever the user changes from "3".
Assuming this is a ListBox_SelectionChanged event, you can do it this way.
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
foreach(var item in e.RemovedItems)
{
if (item.ToString() == 3)
{
//do things
}
}
}
I have a Combo Box that I can already add items to and I want to be able to remove the item I have selected when I hit the delete key.
Here is the code I am using now.
private void commandComboBox_KeyDown(object sender, KeyEventArgs e)
{
var myComboBox = (ComboBox)sender;
string text = myComboBox.Text;
if (e.KeyCode == Keys.Enter)
{
myComboBox.Items.Add(myComboBox.Text); // Add
}
if (e.KeyCode == Keys.Delete)
{
myComboBox.Items.Remove(myComboBox.SelectedItem);
}
}
When I click in the combobox and start typing and then hit enter I hear a windows sound (not sure which one) and then the item is added to the list.
When I hit the dropdown button I see the item there with the text I entered above. When I hit delete the item goes away (at least I think it does) and then when I click somewhere else I get this exception
System.ArgumentOutOfRangeException: InvalidArgument=Value of '0' is not valid for 'index'.
Parameter name: index
Also when I hit the dropdown button I still see the empty spaces
So my question is how do I properly delete items from a ComboBox :)
Also if there is something better then a ComboBox for this kind of thing plz mention them as well, TY
The Windows sound you hear is actually an error beep. Combo boxes do not accept enter key presses, so it's beeping at you "no!" Your code also runs, of course, adding the item, but that doesn't change the fact that the combo box considers you pressing Enter when it has the focus to be an error. If you are intent on the current design, you need to eat the Enter key press after you've received it so that the combo box doesn't go on to try to process it. To do so, set e.SuppressKeyPress to true.
The exception you get is because you've deleted all of the items in the combo box, but some other section of your code tries to get the text of item #0 (the first item). There is no first item because you deleted it, so an exception is thrown. I'm not sure what code it is that's responsible for this, since I can't see it, but I'm guessing you have written a handler for something like the SelectedIndexChanged event.
Indeed, this is a very unusual interface. The purpose of a combo box is to present the user with a list of choices, not to allow them to type in multiple choices. If you want that, use a multi-line text box. At least that way, they'll be able to see all the things that they've entered.
Or, you could use the classic interface idiom for this, where there is a textbox to type into that works with an Add button to add the typed text to a ListBox control. A Delete button deletes the currently selected item in the ListBox. A Clear button clears all of the items in the ListBox. Yes, it is as confusing to use as it is to explain. Avoid these whenever possible. They were more popular in the bad old days of UI design.
Also when I hit the dropdown button I still see the empty spaces
These aren't actually empty spaces. Well, they are, but not really. :-) What I mean is that they are not placeholders representing individual "empty" items. That's just what you see when the entire combo box is empty (contains no items). Because it contains no items, it can't auto-size the height of its drop-down window, so it uses a fixed size.
I had same problem with ComboBox. Noticed that error occurs only if user hits somewhere else after removing the item but not selecting a new one. Solved it by adding selection of new item after removal. Also handled last item as special case. See working code below:
private void comboBox1_KeyDown(object sender, KeyEventArgs e)
{
ComboBox comboBox = sender as ComboBox;
switch (e.KeyCode)
{
case Keys.Delete:
if ((comboBox.DroppedDown) && (comboBox.SelectedItem != null))
{
if (comboBox.Items.Count == 1) // Removing Last Item
{
comboBox.DroppedDown = false;
comboBox.Text = string.Empty;
comboBox.Items.Clear();
}
else
{
comboBox.Items.Remove(comboBox.SelectedItem);
comboBox.SelectedIndex = comboBox.Items.Count - 1;
}
e.Handled = true;
}
break;
}
}
I have a Winform App where I want a user to be able to enter some stock corrections against a list of products which will in turn create a database record for each of those corrections.
Using a combobox, I got it so each item would have to be selected in turn. It works great, but is not very user friendly. Ideally, I'd like a list of products with an empty column to enter the corrections, click submit and ya done.
I looked at using a datagrdiview. I can generate the list of products, but I've no idea on how to create the 'entry column'.
Any suggestions on the path to take?
Cheers,
Numb
EDIT
Here is a mock up of what I would like to do to make it as clear as possible without showing code...
If you want use a ”Submit” button to save a new stock correction, then
approach will be:
-Create a datagridview with products names and empty cell for stock correction
-After ”Submit” button was clicked read ”Correction” columns values, if value exists update database…
Here how you can do it:
Create a datagridview in designer dgvProductCorrections,
then create with designer a two columns in this datagridview
dgvProductCorrection_Product and dgvProductCorrection_Correction.
Put this(or your) columns names in Column .Name property
Then, I assume that you have a class Product where exists a property .Name,
you will need to put a name of this property(in my example will be Name) in .DataProperty of column
Above can be done with designer or in code(Constructor)
Adding a list products List<Product> lstProducts; in datagridview will be as:
dgvProductCorrections.DataSource = lstProducts; //(this may be in Form_Load)
Rememeber before adding a list set a datagridview property AutoGenerateColumns to False
dgvProductCorrections.AutoGenerateColumns = false;
in Button_Click event handler of your Submit button put a code where you loopin through a all rows and reading a correction values. After you can update a database with those values
//Code in Button_Click
{
foreach(DataGridVewRow dgvr in dgvProductCorrections.Rows)
{
Decimal fCorrection;
//Check if value exists and it can be used. Add own other checks
if(dgvr.Cells(this. dgvProductCorrection_Correction.Name).Value != null && Decimal.TryParse(dgvr.Cells(this.dgvProductCorrection_Correction.Name).Value.ToString(), fCorrection) = True)
{
//Here you can put a update code, or save a correction in list and then update all by one update call
}
}
}
Iam using AutoCompleteMode to my textbox. It will append the Bank names to my textbox. So when I started typing with the first leter all the Bank names with first lettre will come to dropdownlist to my textbox. Now my question is
If user try to entre the data which is not im my dropdownlist, the user should not able to entre the text. So i want user to entr the existing bank names only.
Iam using AutoCompleteCustomSource to the textbox for dropdown.
try something like:
bool foundSome = false;
foreach (var bankName in col)
{
foundSome = bankName.StartsWith(textBox.text);
}
if (foundSome)
//Do some action
You can write this code in 'Validating' to preform for each char inserted in txtbox.
the best way to achieve your requierement is to use 1 textbox and 1 combobox. They both should point to the same collection.
Textbox will behave in autocomplete mode as you described. Once you type, combobox value will be set to first matching value from your collection. If no value matches - combobox value should be set to null or default data.
Combobox will store only corresponding data subset with no possibility to edit the chosen text.
Validation and data retrieval will be done from Combobox value.
Advantages of this approach:
- With large sets of data it will be easier for user to find what he/she needs.
- Lesser code to check if input value belongs to data set or to force belonging.
- No validation is needed.
Possible shortcomings:
- One more control at form.
- Logic to synchronize textbox's text and combobox collection should be implemented.
I am creating a windows form app with the following goal:
get a list of products, each with a unique name and a category (from an enumerated list) from a user (and then do some things after, but this is not relevant to the question).
The idea is I would like to have the user specify they would like to configure "n" products by entering a value in a text box. I have the event handler for the text box calling a method which sets a variable to this value n. This value, "n", will be used as the loop counter, or what have you - the point is it will create the bound for the number of boxes to create.
I would then like to add (dynamically based on n), n number of (text box / combo box) pairs to the form. If there is no room to add another (text box / combo box) pair below the last one created, it should create another column.
n is unbounded, but, realistically, will likely never exceed 20. In any event, I'd like to be able to handle it if there are more products than this.
the options in the combo box will be filled from a string list that is passed in at run time, but will be consistent per box, per instance of this Form application.
i tried to enter a mock up image but stack overflow won't let me until i have earned some reputation points :(
I understand how to create a number of boxes using something like the code below, but its the finer points i'm stuck on. Can anyone help?
thanks!
` private void Method1()
{
int boxes = Int32.Parse(NumProducts.Text);
for (int i = 0; i < boxes; i++)
{
TextBox tb = new TextBox();
tb.Location = new System.Drawing.Point(40, i * 20);
tb.Name = "TextBoxName" + i.ToString();
tb.Size = new System.Drawing.Size(184, 20);
tb.TabIndex = i + 2;
tb.Text = String.Empty;
panel1.Controls.Add(tb);
}
}
private void NumProducts_TextChanged(object sender, EventArgs e)
{
Method1();
}`
Sounds to me like a DataGridView would be the better choice here. You can configure it with a DataGridViewTextBoxColumn as the first column and a DataGridViewComboBoxColumn for the second. It supports a "new row" as the last item.
Read the docs. Drop one on a form and play with it.
Asking the user for the number of rows in advance is not very good from a usability viewpoint.
You should rather create an interface that keeps creating new boxes as the user inputs things, either by having a "new row" row that activates when the user types something into it (the empty row isn't saved) or by having a "new row" button.
To achieve the layout, use a FlowLayoutPanel control, and add the controls to this instead of to the panel as you are already doing. That should transparently take care of the columns issue, and add scroll bars if the user goes beyond your anticipated maximum number of edit boxes. General info on the FlowLayoutPanel here (as well as many others).