ComboBox AddRange vs DataSource dinding dilemma

Hi Experts.

I ran into a bit of a dilemma here. Need your advise please.

I have an Array() that's being passed from my Data Layer that I need to bind to the ComboBox.

I need to be able to populate the ComboBox with the array items and add one more item stating "Select User...".

The problem is that if I use cboUsers.DataSource = ...Visual Studio wont allow me to add extra items to the list by doing cboUsers.Items.Add().

and

If I use cboUsers.Items.AddRange() I can't access ValueMembers later on ( not sure why ). It returns Null.

Can anyone advise ?
Thank you.

The code for my Array and ComboBox is below
var userNames = (from u in usersCollection  //IEnumerable collection
                                 select new
                                 {
                                     Id = u.Id,
                                     Name = u.Name
                                 }).ToArray();
                cboUsers.Items.AddRange(userNames);
                cboUsers.DisplayMember = "Name";
                cboUsers.ValueMember = "Id";

Open in new window

LVL 1
techsuppoprtAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Fernando SotoRetiredCommented:
Hi techsuppoprt;

You need to use the DataSource of the ComboBox control as shown below.

var userNames = (from u in usersCollection  //IEnumerable collection
                                 select new
                                 {
                                     Id = u.Id,
                                     Name = u.Name
                                 }).ToArray();

cboUsers.DataSource = userNames;
cboUsers.DisplayMember = "Name";
cboUsers.ValueMember = "Id";

Fernando
0
techsuppoprtAuthor Commented:
Right... as I said.. in that case I have a problem with adding "Select User..." to the combobox.

VIsual Studio does not allow extra stuff to be added to databound objects it seem.
0
Fernando SotoRetiredCommented:
Sorry I was to quick to answer. This is what you need

public class Users
{
    public string Name { get; set; }
    public string id { get; set; }
}


List<Users>  userNames = (from u in usersCollection  //IEnumerable collection
                          select new Users
                          {
                              Id = u.Id,
                              Name = u.Name
                          }).ToList();
           
// Create the item to be inserted into the list
Users selectUser = new Users {Name = "Select User...", id = "0"};
// Insert to list at position 1
userNames.Insert(0, selectUser);

cboUsers.DataSource = userNames;
cboUsers.DisplayMember = "Name";
cboUsers.ValueMember = "Id";
0
Cloud Class® Course: Amazon Web Services - Basic

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

techsuppoprtAuthor Commented:
This is a great solution Fernando, thank you but unfortunately it's not going to work in my specific case just because that Users class isn't available for direct access. You might recall you helped me with some stuff earlier :)

I had an Idea..

The statement below returns an array, right ?

var userNames = (from u in usersCollection  //IEnumerable collection
                                select new
                                {
                                    Id = u.Id,
                                    Name = u.Name
                                }).ToArray();

Array means that I should be able to iterate though it...
What if I iterate through this array somehow, throw it into the BindingSource, add my extra "Select One..." and then DataBid it with the DataGridView.

Can you help me put it together ?
//added points
0
Fernando SotoRetiredCommented:
Hi techsuppoprt;

To your questio:

    The statement below returns an array, right ?
    Answer: It returns an Array of Anonymous type.

    var userNames = (from u in usersCollection  //IEnumerable collection
                                    select new
                                    {
                                        Id = u.Id,
                                        Name = u.Name
                                    }).ToArray();
   
    Array means that I should be able to iterate though it...
    What if I iterate through this array somehow, throw it into the BindingSource,
    add my extra "Select One..." and then DataBid it with the DataGridView.
    Answer: Because you are dealing with Anonymous type of an Array in the function
            or event that you run the above query in this is possible with some
            overhead. Anonymous types are immutable like strings so if you add an
            item to the collection, in the above case userNames, you will be creating
            a completly new collection with the added item leaving Garbage Collection
            to clean up the old Array. From outside the function or event that the
            query was created in which it used the Anonymous type you would need to
            use .Net Reflections Classes to be able to get access to the data.
            Which means that you cannot directly access the values as can be with the
            solution I posted.
           
You state that, "unfortunately it's not going to work in my specific case just because
that Users class isn't available for direct access." If you look at my code below I
show that the Users class can be accessed directly.

Fernando

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
 
namespace WindowsFormsApplication11
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        // List of Users is directly accessable 
        List<Users> userNames;
 
        public class Users
        {
            public string Name { get; set; }
            public string id { get; set; }
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            DbCDataContext db = new DbCDataContext();
 
            userNames = (from c in db.Customers
                         select new Users { Name = c.ContactName, id = c.CustomerID }).ToList();
 
            // Create the item to be inserted into the list
            Users selectUser = new Users {Name = "Select User...", id = "0"};
            // Insert to list at position 1
            userNames.Add(selectUser);
 
            comboBox1.DataSource = userNames;
            comboBox1.DisplayMember = "Name";
            comboBox1.ValueMember = "id";
            
            // Or if you want to use a data binding abd a data grid view then this 
            // will also work
            bindingSource1.DataSource = userNames;
            dataGridView1.DataSource = bindingSource1;
        }
 
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            int index = comboBox1.SelectedIndex;
            // Access the values of the Users class with the use of the comboBox1 control
            Console.WriteLine("User name = {0}\tID = {1}", comboBox1.Text, comboBox1.SelectedValue);
 
            // Access the Users class directly using the selected index of the comboBox1
            Console.WriteLine("User name = {0}\tID = {1}", userNames[index].Name, userNames[index].id);
        }
    }
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
techsuppoprtAuthor Commented:
This is truly awesome.
Thank you for not just answering my question but for going into more details and making sure that I understand it all ! Because I do now!
0
Fernando SotoRetiredCommented:
Not a problem, glad I was able to help.  ;=)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.