I have a System.Timers.Timer
that updates my win form application components in every 开发者_如何学运维5 seconds.
I have a comboBox and global IEnumerable<Person>
list that updated also in everty 5 seconds.
I need to add persons name to combobox. If the name is already in the list, i should not add.
How can I proceed?
Here is the code inside the timer event. This adds multiple times and i am not sure to do that with foreach,
maybe IEnumareble
interface has an easier way.
foreach (Persons person in personsList)
{
comboBox.Items.Add(person.Name);
}
This is one of the simpler solutions to this problem, assuming you're using .NET 3.5 or greater:
foreach(Person person in personsList)
{
if(!comboBox.Items.Cast<string>().Contains(person.Name))
{
comboBox.Items.Add(person.Name);
}
}
If you're using 3.0 or earlier, you'll have to do the search yourself:
foreach(Person person in personsList)
{
bool contains = false;
foreach(string item in comboBox.Items)
{
contains = string.Equals(item, person.Name);
if(contains) break;
}
if(!contains) comboBox.Items.Add(person.Name);
}
If possible using DataBinding is usually good. WPF has even nicer binding allowing for MVVM. WPF would actually make modifications as you modify the original collection (realtime) and don't have to readd all at every pass.
Readding all items at every pass is a bad approach, but its the easy way out. It would be better to either modify the listbox directly if the code allows it (not too many updates, not too time critical) or to make a copy of the list and perform only differences. (Pass 1: Remove any items in combobox that doesn't exist in new list. Pass 2: Add any items in new list that doesn't exist in combobox)
A couple approaches could be to walk all the items in the combobox, or you could keep track of a List of names that you've already added. Do you have any performance requirements?
Easier would be to just bind directly to the list of Persons and set your DisplayMember appropriately...
If I bind the data cmb.DataSource = personsList; cmb.DisplayMember = "Subject"; This wont work
It didn't work for me also. After some trying found this solution, maybe it will help someone:
IEnumerable<ICustomer> customers = GetCustomers(); //fill Ienumerable object list
_comboBox.DataSource = customers.ToList(); //convert it to list and it binds fine
_comboBox.DisplayMember = "Name"; // field Name from ICustomer
_comboBox.ValueMember = "CustomerID"; // field CustomerID from ICustomer
A more simpler approach is:
comboBox.Items.Clear();
comboBox.Items.AddRange(personsList.Select(p => p.Name));
All that does is clears the comboBox and adds the entire list again. Or if you don't like clearing the comboBox:
comboBox.Items.AddRange(personsList.Where(p => !comboBox.Items.Cast<string>().Contains(p.Name)).Select(p => p.Name));
You don't need the foreach
anymore. Simply replace all your code with this!
精彩评论