DataGridViewCombboxColumn Cell Значение и различный раскрывающий список
-
29-09-2019 - |
Вопрос
У меня очень тривиальное требование, которое заставляет меня сходить с ума. У меня 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 для моего требования. Поэтому я использовал это решение.
Другие советы
Я знаю, что это не идеальное решение, но я искал лучшее, и я не нашел, поэтому я пошел на обходной путь
Я сделал следующее:
Когда пользователь открывает
ComboBox
, Я меняюDisplayMember
к"NameWithCode"
Когда пользователь закрыл его, я возвращаю его
"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;
}
}