0

I have a DataGridView with a TextBoxColumn. I would like to be able to click on the cell to enter edit mode, and when I do a drop down will appear with options for the user to pick, or if the user does not want one of those options, they are able to edit the cell (as if there was no drop down). Then when the user leaves the cell, the value (either what they typed, or what they chose) will be saved.

There are lots of answers to adding the user typed choice to the drop down list, but this is not what I want. I just want to have some common options for the user to consider before they go off and make their own choice.

I do not want to have a button to popup another input dialog. I do not want to chanbe the column to a ComboBoxColumn. I do not care if the dropdown arrow is shown at all times or not.

I have tried to change the TextBoxCell to a ComboBoxCell on EditingContolShowing, but this is proving to be a pointless effort.

Are there any suggestions for this?

Tizz
  • 820
  • 1
  • 15
  • 31
  • 1
    It's not clear to me the issue you are having with the ComboBoxColumn type. Why can't you use that? – LarsTech Feb 05 '15 at 17:40
  • 1
    I need it to be a per cell option. Some items in the column will not need a drop down (depending on other values on the row), and others will populate an entirely different list of options to the user. – Tizz Feb 06 '15 at 02:57

2 Answers2

1

One option you could use is AutoComplete. This can mimic most of the desired behavior on a DataGridViewTextCell, with exception of displaying all options on entering the textcell, and without the need of converting the cell type to a ComboBox.

This could be handled in the DataGridView EditingControlShowing event:

private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
  if (e.Control is TextBox)
  {
    TextBox box = e.Control as TextBox;
    box.AutoCompleteCustomSource = new AutoCompleteStringCollection();
    box.AutoCompleteCustomSource.AddRange(new string[] { "Foo", "Bar", "Baz" });
    box.AutoCompleteMode = AutoCompleteMode.Suggest;
    box.AutoCompleteSource = AutoCompleteSource.CustomSource;
  }
}

AutoCompleteDGV

Given, the user must enter text for any option to show. If the desired behavior requires all options to show upon entering the textbox, this would not be your best option. But if that is secondary to all other required behaviors (suggested options, accepts non-option entries, doesn't always have to show, etc), this is a viable solution.

Edit

This worked in all the following situations:

  1. DataGridView is data bound.

Binding the DataSource:

public BindingList<Example> Examples { get; set; }

this.Examples = new BindingList<Example>();
dataGridView1.DataSource = this.Examples;

Where Example is a simple class:

public class Example
{
  public string First { get; set; }
  public string Last { get; set; }
  public string Test { get; set; }
}
  1. Manually adding column(s).

Just an empty column:

DataGridViewTextBoxColumn col = new DataGridViewTextBoxColumn();
col.Name = "Extra";
col.HeaderText = "Extra";
this.dataGridView1.Columns.Add(col);
  1. Both 1 and 2 combined.
OhBeWise
  • 5,350
  • 3
  • 32
  • 60
  • That looks awesome and I would have never thought of that! I implemented exactly what you did, but I cannot get the drop down to appear. Do I need to change some setting on the DGV, or the column to allow this? – Tizz Feb 06 '15 at 02:55
  • @Tizz Have you set a break point to ensure this code is being run? Also, just to clarify for my sake, even when you start typing one of your common options in the textbox the suggestion doesn't appear? If yes to both, then I need to see code on how you set the dgv up and/or any other logic you may have added to `EditControlShowing`. I tried mine several ways and all worked. See the edit in my answer for details. – OhBeWise Feb 06 '15 at 16:50
1

Just set the cells you want to be a ComboBox to the DataGridViewComboBoxCell type:

var cb1 = new DataGridViewComboBoxCell();
cb1.Items.Add("Yes");
cb1.Items.Add("No");
dgv.Rows[1].Cells[1] = cb1;

var cb2 = new DataGridViewComboBoxCell();
cb2.Items.Add("Blue");
cb2.Items.Add("Red");
dgv.Rows[3].Cells[1] = cb2;

Then use the EditingControlShowing event to change the style of the DropDown to allow editing:

void dgv_EditingControlShowing(object sender,
                               DataGridViewEditingControlShowingEventArgs e) {
  ComboBox cb = e.Control as ComboBox;
  if (cb != null) {
    cb.DropDownStyle = ComboBoxStyle.DropDown;
  }
}

Use the CellValidating event to add any typed items into the list that aren't already there:

void dgv_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) {
  var cb = dgv.Rows[e.RowIndex].Cells[e.ColumnIndex] as DataGridViewComboBoxCell;
  if (cb != null && !cb.Items.Contains(e.FormattedValue)) {
    cb.Items.Add(e.FormattedValue);
    if (dgv.IsCurrentCellDirty) {
      dgv.CommitEdit(DataGridViewDataErrorContexts.Commit);
    }
    dgv.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = e.FormattedValue;
  }
}
LarsTech
  • 80,625
  • 14
  • 153
  • 225