DataGridViewCombBoxColumn 单元格值和不同的下拉列表

发布于 2024-09-27 09:28:02 字数 1462 浏览 1 评论 0原文

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

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

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

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

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

此 DisplayMember 列表是绑定到它的数据源中两个字段的组合,即第一部分指向 CustomerCode 字段,第二部分指向客户名称。用户从下拉列表中选择一项后,我需要在组合框单元格中仅显示 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";

I've a very trivial requirement which makes me go nuts. I've a DataGridView in windows forms application. This contains one databound ComboBox Column. I'm using DisplayMember and ValueMember properties of that combobox.

Now my requirement is ComboBox should show the list of DisplayMembers in drop down list but when user selects one item from it, I should display the part of that DisplayMember in the combobox cell visible to the user. For example.

My display member list looks as below:

"Cust1 - Customer 1"
"Cust2 - Customer 2"
"Cust3 - Customer 3"

and when user selects any one of them from the above list (Say user selected 'Cust2 - Customer 2') then I need to display the value in the combobox column cell as only "Cust2" instead of complete DisplayMember text.

This DisplayMember list is a combination of two fields from the datasource bound to it i.e. First part points to CustomerCode field and second part points Customer name. I need to display only CustomerCode in the ComboBox cell after user selects one item from the drop down list.

How can I do this? Or should I come up with my own control which will have a different AutoCompleteCustomSource and display member value. Even I'm confused with that approach too.

Update: As no one has come up with any solution to my problem. Now I'm starting a bounty for that, also if anyone can suggest me other way to implement the same functionality, it would be great.

I've even tried to come up with my own control and tried to work on simple combobox to display a different value than the selected dropdown list, even that didn't work. Is there any other way to implement this? Any tips and tricks are greatly appreciable.

@Anurag: Here is the code which I've used.
Created a datagridview in the design mode. Created one column of type 'DataGridViewComboBoxColumn' that and named it as CustomerColumn.

In the designer file it looks like below:

private System.Windows.Forms.DataGridViewComboBoxColumn CustomerColumn;

This is the entity class which I've used for datasource

 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
 }

In the form load event I'm doing the following:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

苏别ゝ 2024-10-04 09:28:02

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

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

现在我已经在 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”值的下拉列表,如果用户选择其中之一,那么我会将其设置为用户控件中覆盖的文本属性,该属性将用于数据网格视图。现在,基于文本框文本(NameWithCode),我可以获取代码部分并将其设置为文本属性。
如果用户使用组合框下拉按钮来选择项目,那么我将获取组合框选定的文本并将其设置在文本框中,该文本框最终由单元格用于获取值。

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

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

I'm answering my own question because I've implemented my own solution to this by using custom control.

This custom control is created by keeping a textbox above combo box in such a way that only drop down button of combobox is visible.

Now I've created a custom column in datagridview deriving the DataGridViewEditingControl from my usercontrol.

I've added a property in Usercontrol which will take drop down list source from the control which is hosting datagridview.

Now in the EditingControlShowing event I'm setting this property as below

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;
  }
}

This drop down list source is used in the usercontrol to set the autocompletesource to the textbox and datasource to the combobox as below:
Whenever I set the DropDownDataSource I'm firing an event in the usercontrol which will do the following. This is to ensure that every time EditingControlShowing event occurs for this column in DataGridView, this source is updated for textbox and combobox in usercontrol.

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

  comboBox1.DataSource = DropDownListSource;
}

Now whenever user starts typing in the textbox autocomplete source will display dropdown list with 'NameWithCode' values and if user selects one of them then I'll set it to the Text propery overidden in my usercontrol which will be used for the cell value in the DataGridView. Now based on the Textbox text (which is NameWithCode) I can get the code part and set it to the text property.
If user uses combobox dropdown button to select the item then I'll get the combobox selected text and set it in the Textbox which is ultimately used by the cell for getting value.

This way I could achieve the solution I want.

@Homam, solution also works but when I change the ComboBox's DropDownStyle to allow the user to type the value in the combobox it behaves weirdly and not getting up to the mark solution for my requirement. Hence I used this solution.

几味少女 2024-10-04 09:28:02

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

我执行了以下操作:

  1. 当用户打开 < 我将 DisplayMember 更改为 "NameWithCode"

  2. 关闭它时,我将其返回到 "CustCode"

您可以通过 DataGridView.EditingControlShowing 事件。

代码:

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" 启动 DisplayMember

祝你好运!

I know that this is not perfect solution, but I looked for a better one and I didn't find, so I went to a workaround

I did the following:

  1. when the user open the ComboBox, I change the DisplayMember to "NameWithCode"

  2. when the user close it, I return it to "CustCode"

You can Access to the ComboBox control by DataGridView.EditingControlShowing event for the DataGridView.

The code:

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;
        };
}

Note: You have to start the DisplayMember with "CustCode"

Good luck!

云柯 2024-10-04 09:28:02

每次在事件 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;        
  }
}

Each time at the offensive of event dataGridView1_EditingControlShowing there is addition of new handlers for events comboBox.DropDown and comboBox.DropDownClosed. It results in the increase of number of these handlers and their repeated calls. This code decides this problem.

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;        
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文