我有一个非常微不足道的要求让我疯了。我在Windows窗体应用程序中有一个DataGridView。这包含一个数据绑定ComboBox列。我正在使用该组合框的DisplayMember和ValueMember属性。
现在我的要求是ComboBox应该在下拉列表中显示DisplayMembers列表,但是当用户从中选择一个项目时,我应该在用户可见的组合框单元格中显示该DisplayMember的部分。例如。
我的显示成员列表如下所示:
“Cust1 - 客户1” “Cust2 - 客户2” “Cust3 - 客户3”
当用户从上面的列表中选择其中任何一个时(假设用户选择'Cust2 - Customer 2'),我需要将组合框列单元格中的值显示为“Cust2”而不是完整的DisplayMember文本。< / p>
此DisplayMember列表是绑定到它的数据源的两个字段的组合,即第一部分指向CustomerCode字段,第二部分指向客户名称。用户从下拉列表中选择一个项目后,我需要在ComboBox单元格中仅显示CustomerCode。
我该怎么做?或者我应该提出自己的控件,它将具有不同的AutoCompleteCustomSource和显示成员值。即使我也对这种方法感到困惑。
更新:因为没有人能解决我的问题。现在我开始给予赏金,如果有人可以建议我实现相同功能的其他方式,那就太棒了。
我甚至试图想出自己的控件,并尝试使用简单的组合框来显示与所选下拉列表不同的值,即使这样也不起作用。有没有其他方法来实现这个?任何提示和技巧都非常值得注意。
@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";
答案 0 :(得分:3)
我正在回答我自己的问题,因为我已经使用自定义控件实现了我自己的解决方案。
这个自定义控件是通过将文本框保持在组合框上方来创建的,这样只有组合框的下拉按钮才可见。
现在我在datagridview中创建了一个自定义列,从我的usercontrol派生出DataGridViewEditingControl。
我在Usercontrol中添加了一个属性,它将从托管datagridview的控件中获取下拉列表源。
现在在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中用于将autocompletesource设置为文本框,将数据源设置为组合框,如下所示: 每当我设置DropDownDataSource时,我都会在usercontrol中触发一个事件,该事件将执行以下操作。这是为了确保每次在DataGridView中为此列发生EditingControlShowing事件时,都会在usercontrol中为textbox和combobox更新此源。
private void DropDownSourceChanged(object sender, EventArgs eventArgs)
{
textBox1.AutoCompleteCustomSource = DropDownListSource;
textBox1.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
textBox1.AutoCompleteSource = AutoCompleteSource.CustomSource;
comboBox1.DataSource = DropDownListSource;
}
现在每当用户开始在文本框中输入时,自动完成源将显示带有“NameWithCode”值的下拉列表,如果用户选择其中一个,那么我将把它设置为我的usercontrol中覆盖的Text propery,它将用于单元格DataGridView中的值。现在基于Textbox文本(NameWithCode),我可以获取代码部分并将其设置为text属性。 如果用户使用组合框下拉按钮选择项目,那么我将获得组合框所选文本,并将其设置在文本框中,最终由单元格用于获取值。
这样我就可以实现我想要的解决方案。
@Homam,解决方案也可以,但是当我更改ComboBox的DropDownStyle以允许用户在组合框中键入值时,它表现得非常奇怪,而且没有达到我的要求的标记解决方案。因此我使用了这个解决方案。
答案 1 :(得分:2)
我知道这不是完美的解决方案,但我找了一个更好的解决方案而且我找不到,所以我去了解决方法
我做了以下事情:
当用户打开ComboBox
时,我将DisplayMember
更改为"NameWithCode"
当用户关闭它时,我将其返回"CustCode"
您可以通过DataGridView.EditingControlShowing事件访问DataGridView的ComboBox
控件。
代码:
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"
祝你好运!
答案 2 :(得分:0)
每次攻击事件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;
}
}