Значение ячейки DataGridViewCombBoxColumn и другой раскрывающийся список - PullRequest
2 голосов
/ 13 октября 2010

У меня очень тривиальное требование, которое сводит меня с ума. У меня есть DataGridView в приложении Windows Forms. Это содержит один столбец ComboBox с привязкой к данным. Я использую свойства DisplayMember и ValueMember этого списка.

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

Мой список отображаемых элементов выглядит следующим образом:

"Cust1 - Клиент 1" "Cust2 - Клиент 2" "Cust3 - Клиент 3"

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

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

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

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

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

@ Anurag: Вот код, который я использовал. Создал сетку в режиме конструктора. Создан один столбец типа «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";

Ответы [ 3 ]

3 голосов
/ 27 октября 2010

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

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

Теперь я создал пользовательский столбец в datagridview, выводя DataGridViewEditingControl из моего usercontrol.

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

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

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, чтобы задать для автозаполнения текстовое поле, а для источника данных - комбинированный список, как показано ниже: Всякий раз, когда я устанавливаю DropDownDataSource, я запускаю событие в usercontrol, которое будет делать следующее. Это необходимо для того, чтобы каждый раз, когда событие EditingControlShowing происходило для этого столбца в DataGridView, этот источник обновлялся для текстового поля и комбинированного списка в пользовательском контроле.

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

  comboBox1.DataSource = DropDownListSource;
}

Теперь, когда пользователь начинает вводить текст в поле автозаполнения, в источнике автозаполнения будет отображаться раскрывающийся список со значениями «NameWithCode», и если пользователь выберет одно из них, я установлю для него значение Text overydenden в моем usercontrol, которое будет использоваться для ячейки. значение в DataGridView. Теперь, основываясь на текстовом поле Textbox (это NameWithCode), я могу получить часть кода и установить для нее свойство text. Если пользователь использует выпадающую кнопку в выпадающем списке, чтобы выбрать элемент, я получу выделенный в выпадающем списке текст и установлю его в текстовом поле, которое в конечном итоге используется ячейкой для получения значения.

Таким образом, я смогу найти решение, которое хочу.

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

2 голосов
/ 27 октября 2010

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

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

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

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

Вы можете получить доступ к элементу управления ComboBox с помощью DataGridView.EditingControlShowing для 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"

Удачи!

0 голосов
/ 23 февраля 2015

Каждый раз при наступлении события dataGridView1_EditingControlShowing происходит добавление новых обработчиков событий 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;        
  }
}
...