Reputation: 35
I have a class like
public example class {
public string Name {get; set;}
public object A {get; set;}
public object B {get; set;}
....
}
I have a list of examples, and I want to bind the list to a combobox and show by its name.
var examples= new List<example>(){ exampleA, exampleB ,exampleC};
comboBox_ExampleSelect.DataSource = examples;
comboBox_ExampleSelect.DisplayMember = "Name";
when user choose the item in combobox, I can get the selected object
var selectedExample = comboBox_ExampleSelect.SelectedItem;
but when I try to set SelectedItem/SelectedIndex by code, it can't work. I found that the itemsCollection of combobox is null How do I do?
Update 12/22 I found it might be timing issue. I create combobox manualy. It work if I assign datasource after add combobox to main form. Is it necessary?
sample code as follow
public List<Example> _examples = new List<Example>();
public class GUIBox
{
public ComboBox ExampleChooseComboBox;
public GUIBox()
{
ExampleChooseComboBox = new ComboBox()
{
Location = new Point(10, 10),
Name = "comboBox1",
Size = new Size(100, 20),
FormattingEnabled = true
};
}
public void AssignList(List<Example> example)
{
ExampleChooseComboBox.DataSource = new List<Example>(example);
ExampleChooseComboBox.DisplayMember = "Name";
ExampleChooseComboBox.SelectedIndex = 0;
}
}
public Form1()
{
InitializeComponent();
_examples = new List<Example>()
{
new Example() {Id = "1", Name = "Example1"},
new Example() {Id = "2", Name = "Example2"},
};
var gui = new GUIBox();
//gui.AssignList(_examples); ======> fail here
this.Controls.Add(gui.ExampleChooseComboBox);
gui.AssignList(_examples); //======> works here
}
Upvotes: 0
Views: 113
Reputation: 5117
Usually its common to select an item by the value shown in the ComboBox. Below FindString is used to find an item by the property Name. If say (keeping with the class I'm using) you want to find by Id let me know.
Note, .DisplayMember is not set, ToString value is used as .DisplayMember.
public partial class StackoverflowForm : Form
{
public StackoverflowForm()
{
InitializeComponent();
List<Item> list =
[
new Item() { Id = 1, Name = "One" },
new Item() { Id = 2, Name = "Two" },
new Item() { Id = 3, Name = "Three"}
];
comboBox1.DataSource = list;
var xx = list.Select((item, indexer) =>
new { Item = item, Index = indexer }).ToList();
var selected = xx.FirstOrDefault(x => x.Item.Id == 2);
if (selected is not null)
{
comboBox1.SelectedIndex = selected.Index;
}
}
private void SelectedItemButton_Click(object sender, EventArgs e)
{
Item item = comboBox1.SelectedItem as Item;
MessageBox.Show($"Id: {item!.Id} - {item.Name}");
}
}
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
public override string ToString() => Name;
}
Upvotes: 0
Reputation: 9243
Your question states:
I try to set SelectedItem/SelectedIndex by code, it can't work.
The intent of the code you posted seems to be making a list of objects of Example
class and binding that list to a combo box. Your code is assigning items
instead of examples
however, and we have to assume the worst about what items
might be because it's not shown. If you were to follow through with assigning the examples
collection you should be able to set the combo box as you say by either SelectedItem
or SelectedIndex
. Here's some code where I tested it both ways.
public partial class MainForm : Form
{
public MainForm() => InitializeComponent();
protected override async void OnLoad(EventArgs e)
{
base.OnLoad(e);
Example
exampleA = new Example(),
exampleB = new Example(),
exampleC = new Example();
var examples = new List<Example>
{
exampleA,
exampleB,
exampleC,
};
comboBox.DataSource = examples;
comboBox.DisplayMember = "Name";
await localCycleWaitCursor();
// Select exampleB programmatically from index
comboBox.SelectedIndex = 1;
await localCycleWaitCursor();
// Select exampleC programmatically from Example object
comboBox.SelectedItem = exampleC;
async Task localCycleWaitCursor()
{
await Task.Delay(TimeSpan.FromSeconds(2));
Cursor.Position = PointToScreen(new Point(20, 30));
Cursor = Cursors.WaitCursor;
await Task.Delay(TimeSpan.FromSeconds(1));
Cursor = Cursors.Default;
}
}
}
Example class
class Example
{
public Example() => _genID++;
private static char _genID = 'A';
public string Name { get; set; } = $"Example {_genID}";
public object A { get; set; } = $"Object-A-{_genID}";
public string B { get; set; } = $"Object-B-{_genID}";
}
Upvotes: 0