Struct & Enum, Combobox.SelectedItem - c#

The program is a minidatabase-ish thing for product ordering purposes, where I keep the unique orders in a struct, and the productNames in an enum (for practice basically). I only have 3 productnames (Product0, Product1, Product2), and they are added to a combobox (cbo_productNameEdit.DataSource = Enum.GetNames(typeof(productNames));).
Anyway, after saving an order, I want this combobox to change it's selected item to the saved product's name, but it fails to do so. I checked it with a MessageBox, to see if it didn't store it properly...
MessageBox.Show(Orders[cbo_productID.SelectedIndex].productName.ToString());
cbo_productNameEdit.SelectedItem = Orders[cbo_productID.SelectedIndex].productName;
... the messagebox returned Product2, which is indeed the correct one, but the selected item stayed at Product0.

One thing you could do to solve it is to set the SelectedIndex instead of SelectedItem property on the combobox. By default Enums are 0 based integers, so the index will corespond to the value of the enum.
cbo_productNameEdit.SelectedIndex = (int)Enum.Parse(typeof(productNames),
Orders[cbo_productID.SelectedIndex].productName.ToString());

Because you used .DataSource property for filling ComboBox with items
You need to use .SelectedValue for setting selecting item
cbo_productNameEdit.SelectedValue = Orders[cbo_productID.SelectedIndex].productName;
From MSDN: ComboBox.SelectedValue

Related

SelectedItem of a variable combobox

There is a combobox which i fill with this loop
foreach (Machine.Types machine in machineList)
{
cbMachineGUI.Items.Add(machine);
}
after that i want the selected index to be one specific machine.
string machineComboBox = SettingsManager.getParameter("MachineType");
cbMachineGUI.SelectedItem = machineComboBox;
The parameter is correct and set, but the selecteditem of the combobox is always nothing.
if i set the machines in the properties of the combobox (not via the loop) it works. but i need the combobox to be variable.
any suggestions?
The problem is that what you put in Items and what you set SelectedItem to are different types.
You are filling the Items collection with Machine.Types instances, and setting SelectedItem to a string instance.
Using IndexOf like other answers suggest will not help, as this will not do anything that setting SelectedItem does not already do. It still won't find machineComboBox in the Items collection, just like it can't find it now.
You need to use matching types, so do one of these things (depending on how else you use the values in the combobox):
Convert Machine.Types to a string when filling the collection:
cbMachineGUI.Items.Add(machine.ToString());
Convert machineComboBox into an instance of Machine.Types that will match the one in Items when setting SelectedItem - how to do it depends on what Machine.Types is
Find the correct item yourself when setting SelectedItem:
cbMachineGUI.SelectedItem = cbMachineGUI.Items
.OfType<Machine.Types>()
.FirstOrDefault(item => item.ToString() == machineComboBox);
Either way, you must make a conversion between these two types somewhere.
Instead of setting SelectedItem, I suggest you find the item's index and set the selected index.
Something like this:
string machineComboBox = SettingsManager.getParameter("MachineType");
int itemIndex = cbMachineGUI.Items.IndexOf(machineComboBox);
cbMachineGUI.SelectedIndex = itemIndex;
You could try the following:
cbMachineGUI.SelectedIndex = cbMachineGUI.Items.IndexOf("MachineType"); // or whatever you want to select
It could be possible that the item you are trying to set doesn't present in combobox item list and since you haven't actually selected anything it sets to nothing. To check if the item does exist do below
string machineComboBox = SettingsManager.getParameter("MachineType");
if(cbMachineGUI.Items.IndexOf(machineComboBox) >= 0)
cbMachineGUI.SelectedItem = machineComboBox;
Quoting from MSDN documentation:
When you try to set the SelectedItem property to an object, the
ComboBox attempts to make that object the currently selected one in
the list. If the object is found in the list, it is displayed in the
edit portion of the ComboBox and the SelectedIndex property is set to
the corresponding index. If the object does not exist in the list, the
SelectedIndex property is left at its current value.The ComboBox class
searches for the specified object by using the IndexOf method.
Check ComboBox.SelectedItem for more information.

Add object property value to combobox using linq

I have a ComboBox that I am filling with objects to select. I have a LifeCycleObject class with a few properties, one of which is Name and one is TypeID. I am trying to add the Name property to a ComboBox where TypeID = 4 or 5.
Linq Query
_lcObjects = new List<LifeCycleObject>();
cbStep.Items.AddRange(_lcObjects.FindAll(
x => x.TypeID == 5 || x.TypeID == 4
).ToArray());
Which works, but it adds the object Type of EMS.Action.Entities.LifeCycleObject, I can't select the correct one from a combobox where every item is the same, so how do I add the LifeCycleObject.Name instead of the Class name.
You are looking for DisplayMember property and Binding:
cbStep.DisplayMember = "Name";
cbStep.DataSource = _lcObjects.FindAll(x => x.TypeID == 5 || x.TypeID == 4);
This way the names of your objects will be displayed in the ComboBox. And the SelectedValue property will hold the selected object.Note that in order to make this work Name should be a public property in your class not a field.
There’s nothing wrong with what you do. You are adding a list of LifeCycleObjects which you want to select from in your combo box. Now what causes the confusion is the fact that the combo box does not know how to display the objects, so it just calles ToString on the objects. But you likely didn’t overwrite the method, so it will just tell you what the object is called.
So one way would be to overwrite the ToString method so it returns the value of the Name property. A more elegant way however would be to tell the combo box how it should display those objects. How that works depends on what kind of combo box you have: With WPF, you can set the DisplayMemberPath property. With WinForms, you need to set the DisplayMember property.

Combobox SelectedItem does not work

I have the code below
FooCB.DisplayMember = "FooNome";
FooCB.ValueMember = "Foo";
FooCB.DataSource = FooRepository.Instance.All();
FooCB.DataBindings.Add("SelectedItem", Bar, "Foo");
but when I display the form the SelectedItem is always the first.
What am I doing wrong?
I have been struggling a little with the behaviour of Winforms comboboxes and databinding recently and these are my observations (.Net4) when binding the ComboBox.DataSource to a list of items and also binding an object property to ComboBox.SelectedItem.
When binding a list of objects (in your case List<Foo>) to ComboBox.DataSource, the first object in the list is always shown in the combobox.
If you bind an object property to ComboBox.SelectedItem (in your case Bar.Foo) and that object property matches one of the combobox list objects then that object is displayed in the combobox. If the object property is null (Bar.Foo == null) or the object property is not in the combobox list then the first object is shown in the combobox.
Setting ComboBox.SelectedItem = null or ComboBox.SelectedIndex = -1 clears the displayed item on the combobox even though this seems to warn against it. And will set your bound object property to null.
If a user clears the combobox selection when using ComboBox.DropDownStyle == DropDown (with backspace) then the bound object property is set to null.
If you have implemented INotifyPropertyChanged on the object whose property is bound to Combobox.SelectedItem (Bar.Foo) and you programatically set the bound property to a value and that value appears in the combobox list then the changed value will be displayed. If you set the property to null or a value not in the list then the combobox displayed value will not change.
So what can you do about it? The only real issue I have is having no value displayed when my bound property is null so I have just been explicitly setting Combobox.SelectedItem = null as in point #3. You may be able to extend ComboBox and override the default behaviour but so far I have been content with an extra line of code here and there combined with using default values on non-nullable properties.
Probably you are missing some decleration. If you created the Combobox from the Tool Box, -I had the similar problem- you might want to add name of the Combobox's Name as a tag on XAML.
Other than that, if you created it dynamically by code, check if you are missing any decleration for class.
I can't tell from the OP's code whether I'm answering their question, but maybe this will help somebody reading this question. The ComboBox has four ways to set the current value:
SelectedIndex
SelectedItem
SelectedText
SelectedValue
You need to be consistent about what you're setting (and about which event handler you're using). You'll get an error if you set SelectedIndex to something dumb (less than -1 or longer than the list). However, you don't get errors setting the other three to something that doesn't exist for that type of selection.
Suppose you use a Dictionary (that's pseudo code) as a binding source and set DisplayMember = "Value" and ValueMember = "Key", the mapping would look like:
SelectedIndex - -1 to index of last item
SelectedItem - KeyValuePair<Key, Value>
SelectedText - Dictionary value
SelectedValue - Dictionary key
Supplying either value or key to SelectedItem will not generate an error, it will simply act like the OP has described. And that's why I thought this answer might help somebody.
I might also note that, if you're swapping out the contents of the ComboBox, it's not always safe to use SelectedIndex. Suppose the same basic kind of data is in the ComboBox, but selections are limited in some cases compared to others. Using SelectedIndex to persist a previous selection that was still valid in the new list of options is only going work if that previous selection held the exact same place in the list. You'd almost think this was the voice of very, very recent experience speaking...

Detecting change of 'ComboBox' selected item

I have a ComboBox whose items I have populated from a database. I wish to know if the selected item has changed from when I initially displayed the ComboBox. How can I determine this?
it is not simple- try to handle EndEdit event/ But you couldnot handle select change in dropdown list
You could try storing the default value in the .Tag property and comparing the two whenever you need.

ComboBox Items Empty but DataSource Full

After binding a list to combobox, its dataSource.Count is 5 but, combobox item count is 0.
how can it be?
I'm used to Web programming and this is in Windows Forms.
So no combo.DataBind(); method exists.
The problem here is, I'm trying to set the selected item programmatically. Since I don't see the combo.Items collection filled, I cannot set the desired item.
Update
A total update is needed I guess:
datasource contains 7 items
when bound to combobox, DisplayMember and ValueMember are appropriately implemented
after databound, through the gui, I can clearly see the 7 items in the combobox
combobox.DataSource.Count = 7 and combobox.Items.Count = 0
So the problem is here; since after databound no items are there in the ItemCollection of combobox; I cannot search for one to match and set the appropriate one.
Here is a image for better understanding (But I'm pretty sure I'm missing sth simple)
After adding ddl.BindingContext = new BindingContext(); before the BindingSource assignment, everything worked fine.
If you'd expand DataSource items in debuger, you'd probably notice that 1st element on list is null. That is why DataSource does not render ComboBox Items. Removing null items from the list should do all the work;
I had the same problem, but in my case it was caused by calling
combobox.Sorted = True
in InitializeComponent. I guess that call initializes Items, which then prevents the assignment to DataSource from updating it (Items).

Categories