2

我有一个非常微不足道的要求,这让我发疯了。我在 Windows 窗体应用程序中有一个 DataGridView。这包含一个数据绑定的组合框列。我正在使用该组合框的 DisplayMember 和 ValueMember 属性。

现在我的要求是 ComboBox 应该在下拉列表中显示 DisplayMember 列表,但是当用户从中选择一项时,我应该在用户可见的组合框单元格中显示该 DisplayMember 的一部分。例如。

我的显示成员列表如下所示:

“Cust1 - 客户 1” “Cust2 - 客户 2” “Cust3 - 客户 3”

并且当用户从上面的列表中选择其中任何一个时(假设用户选择了“Cust2 - Customer 2”),那么我需要将组合框列单元格中的值显示为仅“Cust2”而不是完整的 DisplayMember 文本。

此 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";
4

3 回答 3

3

我正在回答我自己的问题,因为我已经通过使用自定义控件实现了自己的解决方案。

这个自定义控件是通过在组合框上方保留一个文本框来创建的,这样只有组合框的下拉按钮可见。

现在我在 datagridview 中创建了一个自定义列,从我的用户控件派生 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;
  }
}

这个下拉列表源在用户控件中用于将自动完成源设置为文本框,将数据源设置为组合框,如下所示: 每当我设置 DropDownDataSource 时,我都会在用户控件中触发一个事件,该事件将执行以下操作。这是为了确保每次在 DataGridView 中为该列发生 EditingControlShowing 事件时,都会为用户控件中的文本框和组合框更新此源。

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

  comboBox1.DataSource = DropDownListSource;
}

现在,每当用户开始在文本框中输入时,自动完成源将显示带有“NameWithCode”值的下拉列表,如果用户选择其中之一,那么我会将其设置为我的用户控件中覆盖的 Text 属性,该属性将用于单元格中的值数据网格视图。现在基于文本框文本(即 NameWithCode),我可以获取代码部分并将其设置为文本属性。如果用户使用组合框下拉按钮选择项目,那么我将获取组合框选定的文本并将其设置在文本框中,该文本框最终由单元格用于获取值。

这样我就可以实现我想要的解决方案。

@Homam,解决方案也有效,但是当我更改组合框的 DropDownStyle 以允许用户在组合框中键入值时,它的行为很奇怪,并且没有达到我的要求的标记解决方案。因此我使用了这个解决方案。

于 2010-10-27T13:12:32.570 回答
2

我知道这不是完美的解决方案,但我寻找了一个更好的解决方案但我没有找到,所以我找到了一个解决方法

我做了以下事情:

  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"

祝你好运!

于 2010-10-26T22:59:02.153 回答
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;        
  }
}
于 2015-02-23T14:27:10.930 回答