Solved

How to make a datagridview column work like a combobox with a "dropDown" DropDownStyle

Posted on 2010-11-07
8
3,390 Views
Last Modified: 2012-08-13
How can I make a datagridview column work like a combobox with a "dropDown" DropDownStyle instead of "DropDownList" style (i.e. I can either select from list or type in a new entry)?

 I used the following code to create a combobox column in a datagridview, with its dropdown list portion containing sales rep's names in a table called tblSalesReps.  The problem is, no matter which DataGridViewComboBoxDisplayStyle I choose (DropDownButton, ComboBox or Nothing), the combobox only allows me to pick an existing entry from the list, and doesn't allow me to type in a new entry not already in the list.

           
// Using C# in VS2008...
BindingSource bSrc = new BindingSource();
SqlDataAdapter da = new SqlDataAdapter("SELECT SalesRepID, SalesRep FROM tblSalesReps
                                        ORDER BY SalesRep", conn);  // conn is my open connection
SqlCommandBuilder commandBuilder = new SqlCommandBuilder(da);
DataTable table = new DataTable();
da.Fill(table);
bSrc.DataSource = table;
// Create a new combobox column...
DataGridViewComboBoxColumn newColumn = new DataGridViewComboBoxColumn();
newColumn.DataSource = bSrc;      // Get entries for the dropdown list
newColumn.HeaderText = "MySalesRepComboBox";
// Doesn't matter which style I use here...
newColumn.DisplayStyle = DataGridViewComboBoxDisplayStyle.DropDownButton;
newColumn.DisplayMember = "SalesRep";
newColumn.ValueMember = "SalesRepID";
newColumn.DataPropertyName = "SalesRep";
// Add this new column to grdInfo is my datagridview control...
grdInfo.Columns.Insert(5, newColumn);

Thank you.
eskie
0
Comment
Question by:eskie296
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 4
8 Comments
 
LVL 96

Expert Comment

by:Bob Learned
ID: 34089466
Sometimes, when I want some special behavior that isn't apparent with the DataGridView classes, I attach an event handler to the EditingControlShowing, grab a reference to the underlying editor control, and change the behavior that way.

Proof-of-concept:

DataGridViewComboBoxEditingControl Class
http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridviewcomboboxeditingcontrol.aspx

private DataGridView dataGridView1 = new DataGridView();

private void AddColorColumn()
{
    DataGridViewComboBoxColumn comboBoxColumn =
        new DataGridViewComboBoxColumn();
    comboBoxColumn.Items.AddRange(
        Color.Red, Color.Yellow, Color.Green, Color.Blue);
    comboBoxColumn.ValueType = typeof(Color);
    dataGridView1.Columns.Add(comboBoxColumn);
    dataGridView1.EditingControlShowing +=
        new DataGridViewEditingControlShowingEventHandler(
        dataGridView1_EditingControlShowing);
}

private void dataGridView1_EditingControlShowing(object sender,
    DataGridViewEditingControlShowingEventArgs e)
{
    ComboBox combo = e.Control as ComboBox;
    if (combo != null)
    {
        // Remove an existing event-handler, if present, to avoid 
        // adding multiple handlers when the editing control is reused.
        combo.SelectedIndexChanged -=
            new EventHandler(ComboBox_SelectedIndexChanged);

        // Add the event handler. 
        combo.SelectedIndexChanged +=
            new EventHandler(ComboBox_SelectedIndexChanged);
    }
}

private void ComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
    ((ComboBox)sender).BackColor = (Color)((ComboBox)sender).SelectedItem;
}

Open in new window

0
 

Author Comment

by:eskie296
ID: 34090597
Thanks.  I got the idea, but need to figure out which event handler to add or modify, and try out some actual code.

I was hoping there was an easier way to do this, such as via one of the DataGridViewComboBoxDisplayStyle enum.

eskie

0
 
LVL 96

Accepted Solution

by:
Bob Learned earned 500 total points
ID: 34093251
This is the event handler that you need.  Once you get a reference to the editor (ComboBox), then you should be able to change the drop-down style.  If you can find an easier way to achieve this, let me know...


private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
    ComboBox combo = e.Control as ComboBox;
    if (combo != null)
    {
        // Remove an existing event-handler, if present, to avoid 
        // adding multiple handlers when the editing control is reused.
        combo.SelectedIndexChanged -= new EventHandler(ComboBox_SelectedIndexChanged);

        // Add the event handler. 
        combo.SelectedIndexChanged += new EventHandler(ComboBox_SelectedIndexChanged);
    }
}

Open in new window

0
Salesforce Has Never Been Easier

Improve and reinforce salesforce training & adoption using WalkMe's digital adoption platform. Start saving on costly employee training by creating fast intuitive Walk-Thrus for Salesforce. Claim your Free Account Now

 

Author Comment

by:eskie296
ID: 34099486
Thanks.  Following your code, I used the following handler to set combo's dropdown style:

        private void ComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Change combo box dropdown style to allow typing in a new entry
            ((ComboBox)sender).DropDownStyle = ComboBoxStyle.DropDown;
        }

This does change combo's style to allow typing in a new entry not already in the dropdown list.
However, after I've done that, as soon as I leave this combobox cell, the attached long error message appears:

My intention is simply to have user pick or type in a string, and I will bind this string to a table field.
The combo box is only used to help user pick the string, but they can also type in anything.

In case it is important, I used the following to specify the DisplayMember, ValueMember and DataPropertyName of this combobox.  After I got the above error, I've tried to change ValueMember to "SalesRep"  or simply remove it, and/or remove the DataPropertyName setting, but none of these made any difference and the same error still occurred.
            newColumn.DisplayMember = "SalesRep";
            newColumn.ValueMember = "SalesID";
            newColumn.DataPropertyName = "SalesRep";

Don't know what that error message means, and perhaps I need to handle additional events?

eskie

DataGridError.doc
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 34107179
What are you binding the DataGridViewComboBoxColumn to?  Where are you getting the drop-down list items for that column?
0
 

Author Comment

by:eskie296
ID: 34109153
There are two tables involved.

First table, called tblSalesReps, contains all sales reps records.  It has columns named ‘SalesRepID’, ‘SalesRep’ etc.

Second table, called tblWork, has a column called ‘SalesRep’ which contains a name that may or may not be in tblSalesReps.

My datagridview is bound to tblWork, and on form load, all columns of all rows in tblWork are displayed in the grid.  User can edit any row and changes are automatically saved because the grid is bound to tblWork . Everything works fine.

Now, to help users edit the SalesRep name in this bound grid, I appended a combobox column to the grid.  The dropdown list of this combo comes from ‘SalesRep’ column of tblSalesReps, so user can pick a name without typing.  Alternatively, I want them to be able to also type in a new name not already in tblSalesReps (and I don’t want to add that new name to tblSalesReps).  That’s why I am asking this question.  

I also bind this combo box column to the ‘SalesRep’ field of tblWork, so that whatever name user picks from list or types in will be automatically saved to the ‘SalesRep’ field of tblWork.  So, I currently have a text column and combobox column both of which are bound to the same ‘SalesRep’ field of tblWork.  This is redundant but doesn’t cause a problem.  I do plan to get rid of the text column after the combobox column has worked the way I want.

Attached is the code I used to achieve the above.

Thanks.
Eskie


Code.txt
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 34161190
I don't have any idea about your problem space, and because of my own problems to solve, I haven't had time to come up with any kind of solution to this.
0
 

Author Comment

by:eskie296
ID: 34161339
That's understandable.  I don't mean to bog you down with lots of details or end up with debugging my code,  I just wanted to make sure I am not missing something obvious.  Your suggestion of using event handler to customize grid column is useful and with it I have made the combo box a dropdown style.  I will try to finish it by binding the text user typed in to a table field.

Thanks.
eskie

0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
Monitoring a network: why having a policy is the best policy? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the enormous benefits of having a policy-based approach when monitoring medium and large networks. Software utilized in this v…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…

688 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question