DataGridViewCombboxColumn Cell Значение и различный раскрывающий список

StackOverflow https://stackoverflow.com/questions/3921579

Вопрос

У меня очень тривиальное требование, которое заставляет меня сходить с ума. У меня DataGridView в приложении Windows Forms. Он содержит один столбец Combobox Databound. Я использую свойства Displaymember и Valuemember этого комбо.

Теперь мое требование состоит в том, что ComboBox должен отображать список элементов отображения в раскрывающемся списке, но когда пользователь выбирает из него один элемент, я должен отобразить часть этого показателя Display в ячейке ComboBox, видимой для пользователя. Например.

Мой список участников отображения смотрит, как ниже:

"CUST1 - Клиент 1" "CUST2 - Клиент 2" "CUST3 - Клиент 3"

и когда пользователь выбирает любого из них из приведенного выше списка (скажем, пользователь выбрал 'CUST2 - Customer 2'), мне нужно отобразить значение в ячейке столбца ComboBox как только «CUST2» вместо полного текста отображения.

Этот список отображения представляет собой комбинацию из двух полей из данных, связанного с ним, то есть первой части указывает на поле Customercode и имя клиента второй части. Мне нужно отобразить только Customercode в ячейке ComboBox после того, как пользователь выбирает один элемент из раскрывающегося списка.

Как я могу это сделать? Или я должен придумать свой собственный контроль, который будет иметь другое значение AutoCompleteCustomSource и отобразить значение члена. Даже я тоже в замешательстве с таким подходом.

Обновлять: Поскольку никто не придумал какого -либо решения моей проблемы. Теперь я начинаю щедрость для этого, также если кто -то может предложить мне другой способ реализации той же функциональности, это было бы здорово.

Я даже попытался придумать свой собственный контроль и попытался работать над Simple Combobox, чтобы отобразить другое значение, чем выбранное раскрытие, даже это не сработало. Есть ли другой способ реализовать это? Любые советы и хитрости очень заметны.

@Anurag: Вот код, который я использовал. Создал DataGridView в режиме дизайна. Создал один столбец типа «DataGridViewComboboxColumn», который назвал его как CustomerColumn.

В дизайнерском файле это выглядит ниже:

private System.Windows.Forms.DataGridViewComboBoxColumn CustomerColumn;

Это класс объектов, который я использовал для данных

 public class Customer
 {
    public int Id { get; set; }
    public string CustCode { get; set; }
    public string CustName { get; set; }
    public string NameWithCode { get; set; }// CustCode - CustName format
 }

В событии загрузки формы я делаю следующее:

  CustomerColumn.DataSource = GetCustomers();
  CustomerColumn.DisplayMember = "NameWithCode";
  CustomerColumn.ValueMember = "Id";
Это было полезно?

Решение

Я отвечаю на свой собственный вопрос, потому что я реализовал свое собственное решение для этого, используя пользовательский элемент управления.

Этот пользовательский элемент управления создается путем сохранения текстового поля над комбо -поле таким образом, что видна только кнопка «Комбобокс».

Теперь я создал пользовательский столбец в DataGridView, получая DataGridViewedItingControl из моего USERCONTROL.

Я добавил свойство в UserControl, которое приведет к источнику раскрывающегося списка из управления, который ведет Hosting DataGridView.

Теперь в событии EditingControlShoing я устанавливаю это свойство, как ниже.

private void dataGridView2_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
  if(dataGridView2.CurrentCell.ColumnIndex.Equals(0) && e.Control is UserControl1)
  {
    var uscontrol = e.Control as UserControl1;
    uscontrol.DropDownListSource = source;
  }
}

Этот выпадающий источник списка используется в UserControl для установки AutoCompleteSource в текстовый поле и DataSource для ComboBox, как показано ниже: всякий раз, когда я устанавливаю выпадающий в действие, я запускаю событие в UserControl, который будет выполнять следующее. Это должно убедиться, что каждый раз, когда для этого столбца происходит событие редактирования ControlShoving, этот источник обновляется для TextBox и ComboBox в UserControl.

private void DropDownSourceChanged(object sender, EventArgs eventArgs)
{
  textBox1.AutoCompleteCustomSource = DropDownListSource;
  textBox1.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
  textBox1.AutoCompleteSource = AutoCompleteSource.CustomSource;

  comboBox1.DataSource = DropDownListSource;
}

Теперь, когда пользователь начинает набирать ввод в источнике автозаполнения TextBox, будет отображать раскрытый список со значениями «namewithCode», и если пользователь выберет один из них, я установите его на текстовую пропукренную пропущенную в моем USERCONTROL, который будет использоваться для значения ячейки в DataGridView. Теперь на основе текста Textbox (который является namewithcode), я могу получить кодовую часть и установить ее в текстовое свойство. Если пользователь использует выпадающую кнопку ComboBox, чтобы выбрать элемент, я получу выбранное текст ComboBox и установлю его в текстовом поле, который в конечном итоге используется ячейкой для получения значения.

Таким образом, я мог бы достичь желаемого решения.

@Homam, решение также работает, но когда я меняю раскрывающееся вмешательство ComboBox, чтобы позволить пользователю вводить значение в ComboBox, он ведет себя странно и не достигает решения Mark для моего требования. Поэтому я использовал это решение.

Другие советы

Я знаю, что это не идеальное решение, но я искал лучшее, и я не нашел, поэтому я пошел на обходной путь

Я сделал следующее:

  1. Когда пользователь открывает ComboBox, Я меняю DisplayMember к "NameWithCode"

  2. Когда пользователь закрыл его, я возвращаю его "CustCode"

Вы можете получить доступ к ComboBox контроль DataGridView.editingControlShoing Событие для DataGridView.

Код:

private void dataGridView1_EditingControlShowing(object sender, 
    DataGridViewEditingControlShowingEventArgs e)
{
    var comboBox = e.Control as ComboBox;

    comboBox.DropDown += (s1, e1) => comboBox.DisplayMember = "NameWithCode";

    comboBox.DropDownClosed += (s2, e2) =>
        {
            // save the last selected item to return it after 
            // reassign the Display Member
            var selectedItem = comboBox.SelectedItem; 

            comboBox.DisplayMember = "CustCode";
            comboBox.SelectedItem = selectedItem;
        };
}

Примечание: вы должны начать DisplayMember с "CustCode"

Удачи!

Каждый раз в наступлении событий DataGridView1_editingControlShoing есть добавление новых обработчиков для событий combobox.dropdown и combobox.dropdownclosed. Это приводит к увеличению числа этих обработчиков и их повторных вызовов. Этот код решает эту проблему.

private void dataGridView1_EditingControlShowing(object sender, 
      DataGridViewEditingControlShowingEventArgs e)
{
  var comboBox = e.Control as ComboBox;

  comboBox.DropDown += comboBox_DropDown;
  comboBox.DropDownClosed += comboBox_DropDownClosed;
}

private void comboBox_DropDown(object sender, System.EventArgs e)
{
  var comboBox = sender as ComboBox;
  if(comboBox != null)
  {
    comboBox.DropDown -= comboBox_DropDown;
    comboBox.DisplayMember = "NameWithCode";        
  }
}

private void comboBox_DropDownClosed(object sender, System.EventArgs e)
{
  var comboBox = sender as ComboBox;
  if(comboBox != null)
  {
    comboBox.DropDownClosed -= comboBox_DropDownClosed;

    var selectedItem = comboBox.SelectedItem; 

    comboBox.DisplayMember = "CustCode";
    comboBox.SelectedItem = selectedItem;        
  }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top