【问题标题】:How to select an item from combobox by key?如何按键从组合框中选择一个项目?
【发布时间】:2019-07-02 15:10:31
【问题描述】:

我填充组合框从数据库中获取数据

这是我的数据库结构:

Table names

ID ------ Name

1  ------ John
2  ------ Sarah
3  ------ Peter

这是我的班级结构

// Class structure

    public class Names
    {
        public int id;
        public string name;
    }

这就是我声明我的字典以及我如何设置它的方式

// Declare dictionary
Dictionary<int, string> dataSouceNames;

public MyProgram()
{
    InitializeComponent();
    dataSouceNames = getComboDataSourceNames();
}

//Dictionary
private Dictionary<int, string> getComboDataSourceNames()
{
    Dictionary<int,string> comboSource = new Dictionary<int,string>();

    List<Names> res = dataProvider.getAllNames();

    foreach (Names item in res)
    {
        comboSource.Add(item.id, item.nome);
    }

    return comboSource;
}

这是我用来从数据库中获取数据的 SQL

getAllNames()
{
    string sql = "SELECT * FROM names";
}

最后我如何填充我的 ComboBox

// Function fill combobox
private void initComboNames()
{
    cmbNames.DataSource = new BindingSource(dataSourceNames, null);
    cmbNames.DisplayMember = "Text";
    cmbNames.ValueMember = "Value";
}

然后我尝试按键选择组合框中的项目:

    cmbNames.SelectedItem = Names.ID // WHERE Names.ID is number "2"

我希望输出“Sarah”为 SelectedIndex,但我知道我做错了。

【问题讨论】:

  • 什么是数据源? dataSourceNames 还是 dataSouceCantieri?如果是dataSouceCantieri,那么cmbNames.SelectedItem = new KeyValuePair&lt;int, string&gt;(Names.ID, dataSouceCantieri[Names.ID]);。你应该有.DisplayMember = "Value"(对应于字符串,Name)和.ValueMember = "Key"dataSourceNames 未声明且未确定。
  • 你好@Jimi 你的解决方案已经奏效了,同时我不明白你做了什么!我读到这不是聊天,但如果你能解释一下你写了什么,那就太酷了。顺便说一句,谢谢

标签: c# winforms combobox key


【解决方案1】:

为什么我建议使用这种赋值来设置 ComboBox 的当前项:

cmbNames.SelectedItem = new KeyValuePair<int, string>(Names.ID, dataSouceCantieri[Names.ID]);

还可以像这样定义 DisplayMemberValueMember 属性:

cmbNames.DisplayMember = "Value";
cmbNames.ValueMember = "Key";
cmbNames.DataSource = new BindingSource(dataSouceCantieri, null);

这与您设置 [ComboBox].DataSource = [Dictionary&lt;TKey, TValue&gt;]; 时发生的情况有关。
好吧,实际上你不能那样做。 Dictionary 是一个复杂的对象,它不直接由控件的DataSource 属性管理;它只接受实现IListIListSource 的复杂对象。字典没有。

您当然可以将 Dictionary 转换为 List,现在可以接受:

[ComboBox].DataSource = [Dictionary<TKey, TValue>].ToList();

我们提供了一个 List&lt;KeyValuePair&lt;TKey, TValue&gt;&gt;,它实现了 IList&lt;T&gt;
此外,List 的每个元素都是一个KeyValuePair&lt;TKey, TValue&gt;
此对象公开两个属性:KeyValue,允许访问对象的内部值。
Dictionary 仅公开Keys 集合和Values 集合属性。其他复杂对象。

当您将 BindingSource.DataSource 设置为 Dictionary 时,此类执行相同的操作:它测试我们分配的对象是实现 IList 还是 IListSource;如果没有,它会创建一个新的BindingList 并使用IEnumerable.GetEnumerator() 方法从集合中提取元素。
Dictionary.GetEnumerator() 将集合中的每个元素返回为KeyValuePair&lt;TKey, TValue&gt;,同调用[Dictionary].ToList()

在 .Net 参考源中查看此行为:

BindingSource main constructor
IList list = [BindingSource].GetListFromEnumerable()
private static IList CreateBindingList(Type type)

所以,当我们分配这个时:

cmbNames.DataSource = new BindingSource(dataSourceNames, null);

我们实际上将控件的 DataSource 设置为 IList&lt;KeyValuePair&lt;TKey, TValue&gt;&gt;
因此,每个ComboBox.Item 都是KeyValuePair&lt;TKey, TValue&gt;
KeyValuePair&lt;int, string&gt;,在这里。
这就是为什么我们可以设置:

[ComboBox].DisplayMember = "Value";
[ComboBox].ValueMember = "Key";

这些是KeyValuePair&lt;TKey, TValue&gt; 类公开的属性的名称。

由于 ComboBox 的每个 Item 都是一个 KeyValuePair&lt;int, string&gt;,要选择一个 item,使其成为当前 item,我们可以将其设置为特定的 KeyValuePair&lt;int, string&gt;
在您的情况下,密钥由 Names.ID 属性提供:

cmbNames.SelectedItem = new KeyValuePair<int, string>(Names.ID, dataSouceCantieri[Names.ID]);

我使用了这种形式:new KeyValuePair&lt;int, string&gt;(Names.ID, dataSouceCantieri[Names.ID]),因为这样我们可以直接通过Key访问字典dataSouceCantieri,所以这是O(1)操作.

胜过写作:

cmbNames.SelectedItem = dataSouceCantieri.FirstOrDefault(dict => dict.Key == Names.ID); 

或类似的。此方法意味着迭代集合,直到找到正确的元素或没有找到。

【讨论】:

  • 你就是男人!这个解释是你能做的最好的,在微软文档中我都找不到类似的解释!我想捐款
【解决方案2】:

首先你以这种方式填充组合框。这样,组合框将向用户显示名称(显示成员),但是当您选择索引时,它将为您提供 ID(值成员)

SQL.con.Open();
DataTable tb = new DataTable();
SqlCommand cmd = new SqlCommand("select columnID,Name from TableName",SQL.con);
SqlDataReader dr;
dr = cmb.ExecuteReader();
tb.Load(dr);
comboBox.DisplayMember = "Name";
comboBox.ValueMember = "columnID";
comboBox.DataSource = tb; 

完成后,您可以简单地通过

获取 id
int id =  comboBox.SelectedValue;

记住像 comboboc , columnId 等字段与您的愿望字段的变化

【讨论】:

    【解决方案3】:

    我认为您必须传递姓名(“Sarah”而不是 Id“2”),如果不可能,请使用 SelectedValue。

    cmbNames.SelectedValue = Names.Id;
    

    否则如果你知道索引,就可以这样做

    cmbNames.SelectedIndex= 1;
    

    【讨论】:

    • 不幸的是,我没有索引,也无法传递名称“Sarah”,因为在我的数据库中,我将值保存为数字...
    • 你可以试试这个看看 -> cmbNames.SelectedValue = Names.Id;上面也更新了答案。
    猜你喜欢
    • 2018-01-23
    • 2014-11-28
    • 2013-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多