C# DataGridViewComboxColumn单元格值和不同下拉列表
我有一个非常琐碎的要求,这让我发疯。我在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 在设计器文件中,它如下所示: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
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”
组合框
控件
守则:
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:很抱歉最后的评论。我在用