C# DataGridViewComboxColumn单元格值和不同下拉列表

C# DataGridViewComboxColumn单元格值和不同下拉列表,c#,winforms,datagridview,drop-down-menu,datagridviewcombobox,C#,Winforms,Datagridview,Drop Down Menu,Datagridviewcombobox,我有一个非常琐碎的要求,这让我发疯。我在windows窗体应用程序中有一个DataGridView。它包含一个数据绑定组合框列。我正在使用该组合框的DisplayMember和ValueMember属性 现在我的要求是ComboBox应该在下拉列表中显示DisplayMembers的列表,但当用户从中选择一项时,我应该在ComboBox单元格中显示该DisplayMembers的一部分,该部分对用户可见。比如说 我的显示成员列表如下所示: “客户1-客户1” “客户2-客户2” “客户3-客户3

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

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

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

“客户1-客户1” “客户2-客户2” “客户3-客户3”

当用户从上面的列表中选择任意一个(比如用户选择了'Cust2-Customer 2')时,我需要在combobox列单元格中仅显示“Cust2”值,而不是完整的DisplayMember文本

此DisplayMember列表由绑定到它的数据源中的两个字段组成,即第一部分指向CustomerCode字段,第二部分指向CustomerName。在用户从下拉列表中选择一项后,我只需要在组合框单元格中显示CustomerCode

我该怎么做?或者我应该使用自己的控件,该控件将具有不同的AutoCompleteCustomSource和显示成员值。甚至我也对这种方法感到困惑

更新:因为还没有人想出任何解决我问题的办法。现在我开始为此悬赏,如果有人能建议我用其他方法实现同样的功能,那就太好了

我甚至尝试使用自己的控件,并尝试使用简单的组合框来显示与所选下拉列表不同的值,即使这样也不起作用。有没有其他方法来实现这一点?任何提示和技巧都是非常值得欣赏的

@阿努拉格:这是我用过的代码。 在设计模式下创建了datagridview。创建了一个类型为“DataGridViewComboxColumn”的列,并将其命名为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
 }
在form load事件中,我将执行以下操作:

  CustomerColumn.DataSource = GetCustomers();
  CustomerColumn.DisplayMember = "NameWithCode";
  CustomerColumn.ValueMember = "Id";

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

我做了以下工作:

  CustomerColumn.DataSource = GetCustomers();
  CustomerColumn.DisplayMember = "NameWithCode";
  CustomerColumn.ValueMember = "Id";
  • 当用户打开
    组合框时,我将
    显示成员
    更改为
    “NameWithCode”

  • 当用户关闭它时,我将其返回到
    “CustCode”

  • 您可以通过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;
            };
    }
    
    注意:您必须使用
    “CustCode”


    祝你好运

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

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

    现在,我已经在datagridview中创建了一个自定义列,从我的usercontrol派生DataGridViewEditingControl

    private void DropDownSourceChanged(object sender, EventArgs eventArgs)
    {
      textBox1.AutoCompleteCustomSource = DropDownListSource;
      textBox1.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
      textBox1.AutoCompleteSource = AutoCompleteSource.CustomSource;
    
      comboBox1.DataSource = DropDownListSource;
    }
    
    我在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设置为textbox,将datasource设置为combobox,如下所示: 每当我设置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;
    }
    
    现在,每当用户开始在文本框中键入时,autocomplete source将显示带有“NameWithCode”值的下拉列表,如果用户选择其中一个值,则我将在我的usercontrol中将其设置为Text属性overidden,该属性将用于DataGridView中的单元格值。现在,基于文本框文本(即NameWithCode),我可以获取代码部分并将其设置为text属性。 如果用户使用combobox下拉按钮选择项目,那么我将获得combobox selected文本,并将其设置在Textbox中,该文本框最终由单元格用于获取值

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


    @Horam,解决方案也有效,但当我更改组合框的下拉样式以允许用户在组合框中键入值时,它的行为异常,无法达到我要求的标准解决方案。因此,我使用了这个解决方案。

    每次在事件dataGridView1\u EditingControls的攻击中,都会显示为事件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;        
      }
    }
    

    为什么不将值成员设置为“Cust1”@国王:但我不希望值成员作为下拉列表。gridview中的组合框!数据源到底是什么…我的意思是,您用来填充网格/组合框的代码是什么?我可能会有一个solution@Anurag:它是datagridview,其中一列的类型为comboboxcolumn。对于这个comboboxcolumn,我分配了一个数据源,它是一个简单的客户对象{Id,CustCode,CustName}。我将用将数据源分配到组合框来更新这个问题。@Homam:谢谢你的回答。我已经试过这个方法了。我无法继续使用此解决方案,因为更改显示成员会影响该列中的所有单元格,这是我不希望看到的。这甚至会给最终用户带来困惑。所以我选择了退出这个解决方案。不管怎样,如果用户体验不是问题,这是一个很好的解决方案。@JPReddy:对不起,我不理解您的问题,更改必须只影响ComboBox控件,因此它不能影响本栏或其他栏中的任何其他单元格,所以您可以解释更多。@Homam:很抱歉最后的评论。我在用