C# 为具有KeyValuePair列表作为数据源的组合框选择初始选定值

C# 为具有KeyValuePair列表作为数据源的组合框选择初始选定值,c#,winforms,visual-studio-2013,C#,Winforms,Visual Studio 2013,我正在从KeyValuePair的列表创建一个组合框。到目前为止,它在为用户提供描述性名称的同时返回一个数字id方面工作得非常好。然而,无论我如何尝试,我都无法选择最初选择的值 public StartUpForm() { InitializeComponent(); FlowLayoutPanel flowLayout = new FlowLayoutPanel(); //This is necessary to protect the table, which is for

我正在从
KeyValuePair
列表创建一个组合框。到目前为止,它在为用户提供描述性名称的同时返回一个数字id方面工作得非常好。
然而,无论我如何尝试,我都无法选择最初选择的值

public StartUpForm()
{
    InitializeComponent();

    FlowLayoutPanel flowLayout = new FlowLayoutPanel(); //This is necessary to protect the table, which is for some reason collapsing...
    flowLayout.FlowDirection = FlowDirection.TopDown;
    flowLayout.AutoSize = true;
    flowLayout.AutoSizeMode = AutoSizeMode.GrowAndShrink;

    var comboBox = new ComboBox();

    {
        var choices = new List<KeyValuePair<int, string>> ();
        choices.Add(new KeyValuePair<int, string>(1, "hello"));
        choices.Add(new KeyValuePair<int, string>(2, "world"));
        comboBox.DataSource = choices;
        comboBox.ValueMember = "Key";
        comboBox.DisplayMember = "Value";
        flowLayout.Controls.Add(comboBox);
    }
    Controls.Add(flowLayout);

    //None of these work:
    comboBox.SelectedValue = 2;
    comboBox.SelectedValue = 2.ToString();
    comboBox.SelectedValue = new KeyValuePair<int, string>(2, "world");
    comboBox.SelectedValue = "world";
    comboBox.SelectedItem = 2;
    comboBox.SelectedItem = 2.ToString();
    comboBox.SelectedItem = new KeyValuePair<int, string>(2, "world");
    comboBox.SelectedItem = "world";

    return;
}
publicstartupForm()
{
初始化组件();
FlowLayoutPanel flowLayout=new FlowLayoutPanel();//这是保护表所必需的,该表由于某种原因正在崩溃。。。
flowLayout.FlowDirection=FlowDirection.TopDown;
flowLayout.AutoSize=true;
flowLayout.AutoSizeMode=AutoSizeMode.GrowthandShrink;
var comboBox=新的comboBox();
{
var choices=newlist();
添加(新的KeyValuePair(1,“hello”);
添加(新的KeyValuePair(2,“世界”);
comboBox.DataSource=选项;
comboBox.ValueMember=“Key”;
comboBox.DisplayMember=“值”;
flowLayout.Controls.Add(组合框);
}
控件。添加(flowLayout);
//这些都不起作用:
comboBox.SelectedValue=2;
comboBox.SelectedValue=2.ToString();
comboBox.SelectedValue=新的KeyValuePair(2,“世界”);
comboBox.SelectedValue=“世界”;
comboBox.SelectedItem=2;
comboBox.SelectedItem=2.ToString();
comboBox.SelectedItem=新的KeyValuePair(2,“世界”);
comboBox.SelectedItem=“世界”;
返回;
}
结果总是一样的:


如何使用
列表作为数据源在
组合框中选择最初选择的值?

绑定在构造函数中工作不太好,因此请尝试将组合框声明移动到表单范围,并尝试使用OnLoad覆盖:

ComboBox comboBox = new ComboBox();

protected override void OnLoad(EventArgs e) {
  comboBox.SelectedValue = 2;
  base.OnLoad(e);
}

为什么要使用绑定?创建一个具有int和string属性的类并重写ToString()以显示字符串文本不是更容易吗

public class ComboItem
{
    public int Key {get; set;}
    public string Text {get; set;}
    public override string ToString()
    {
        return this.Text;
    }
}

public void OnFormLoad(object Sender, ...)
{
    IEnumerable<ComboItem> comboItems = CreateListComboItems();
    this.ComboBox1.Items.Clear();
    foreach (var comboitem in comboItems)
    {
        this.comboBox1.Items.Add(comboItem);
    }
 }
附录:我无法选择最初选择的值。

我猜您希望能够以编程方式选择具有给定值的键的组合框项,从而使组合框显示属于该键的文本

尽管属性ComboBox.Items属于ComboBoxCollection类型,但它实现了IEnumerable,这意味着您可以对其使用Enumerable.Cast()将其强制转换为ComboItems序列。使用Linq查找是否有具有请求键的ComboItem并选择第一个找到的ComboItem,或者如果没有具有此键的ComboItem,则选择或不选择任何内容

// selects the combobox item with key == value
private void SelectComboItem(int value)
{
   this.comboBox1.SelectedItem = 
       this.ComboBox1.Items.Cast<ComboItem>()
           .FirstOrDefault(comboItem => comboItem.Key == value);
}
//选择key==value的组合框项
私有void SelectComboItem(int值)
{
this.comboBox1.SelectedItem=
this.ComboBox1.Items.Cast()
.FirstOrDefault(comboItem=>comboItem.Key==value);
}
代码将获得组合框中的项目集合(我们知道这是一个ComboItems序列),因此我们可以将所有项目强制转换为一个ComboItem。
然后,我们尝试查找第一个键等于value的ComboItem。如果没有这样的ComboItem,则返回null。最后将其作为所选项目。空值表示不选择任何内容

!谢谢一个问题:人们怎么会知道这一点?@安东尼奥也有同样的问题。多年前。为什么要重新发明轮子?你的意思是为什么要重用已经被证明有效的模式?好的,(1)易于使用,(2)易于理解您的类的未来更改,(3)易于更改,例如,如果将来我们需要两个关键值,而不是一个提示。但我必须说,这并没有解决我的问题,即选择最初选择的值。你读过其他答案吗?:)它解释了为什么我不能选择最初选择的值(在我表单的构造函数中)。我知道这是绑定方法的问题。我只是展示了避免绑定是多么容易,如果在不久的将来您需要的不仅仅是一个int字符串对,那么它的优点是什么。考虑两种方法所需的变化。考虑一下对于那些还没有看过代码的人来说,哪种方法更容易理解。哪种方法看起来像魔术,哪种方法似乎是解决它的自然方法。
// selects the combobox item with key == value
private void SelectComboItem(int value)
{
   this.comboBox1.SelectedItem = 
       this.ComboBox1.Items.Cast<ComboItem>()
           .FirstOrDefault(comboItem => comboItem.Key == value);
}