2015-09-23 7 views
12

Sto creando una combobox da di KeyValuePair<int, string>. Fino ad ora ha funzionato molto bene nell'offrire all'utente il nome descrittivo mentre mi restituiva un id numerico.
Tuttavia, qualunque cosa provi, non sono in grado di scegliere il valore inizialmente selezionato.Scelta del valore inizialmente selezionato per un ComboBox con un elenco di KeyValuePair come DataSource

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

il risultato è sempre lo stesso:

enter image description here

Come posso scegliere il valore inizialmente selezionato in una ComboBox utilizzando come DataSource un List<KeyValuePair<int, string>>?

risposta

8

Binding non funziona molto bene all'interno del costruttore, in modo da provare a spostare la dichiarazione ComboBox al campo di applicazione forma e provare a utilizzare l'override OnLoad:

ComboBox comboBox = new ComboBox(); 

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

Fantastico, funziona! Grazie! Una domanda: come si dovrebbe sapere questo? – Antonio

+0

@Antonio ha avuto lo stesso problema. . . anni e anni fa. – LarsTech

0

Perché stai usando vincolante? Non sarebbe più facile creare una classe con l'int e le proprietà di stringa e di override ToString() per visualizzare il testo della stringa:

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

Iscriviti all'evento SelectedIndexChanged comboBox:

private void OnComboSelectedIndexChanged(object sender, EventArgs e) 
{ 
    ComboItem selectedItem = (ComboItem)this.comboBox1.SelectedItem; 
    ProcessSelectedKey(selectedItem.Key); 
} 

Addendum : Non sono in grado di scegliere il valore inizialmente selezionato.

Immagino che vogliate essere in grado di selezionare a livello di codice l'elemento della casella combinata che ha una chiave con un determinato valore, facendo sì che il ComboBox visualizzi il testo che appartiene a quella chiave.

Sebbene la proprietà ComboBox.Items sia di tipo ComboBoxCollection, implementa IEnumerable, ovvero è possibile utilizzare Enumerable.Cast() su di esso per eseguire il cast in una sequenza di ComboItems. Utilizzare LINQ per trovare se c'è un ComboItem con la chiave richiesta e selezionare il primo trovato ComboItem, o selezionare o selezionare nulla se non v'è alcun ComboItem con questa chiave

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

Il codice otterrà la collezione di oggetti in casella combinata (che sappiamo è una sequenza di ComboItems), quindi possiamo lanciare tutti gli elementi su un ComboItem. Quindi proviamo a trovare il primo ComboItem che abbia una chiave uguale al valore. Restituisce null se non esiste tale ComboItem. Finalmente rendilo l'oggetto selezionato. Un valore di null indica di selezionare nulla

+1

Perché reinventare la ruota? – Antonio

+0

Intendi perché riusare i modelli che hanno dimostrato di funzionare? Bene (1) facilità d'uso, (2) facilità di comprensione per i futuri cambiamenti della tua classe, (3) facilità di cambiamento, ad esempio se in futuro avremo bisogno di due valori chiave invece di uno –

+0

Grazie per il tuo suggerimento. Devo dire però che questo non affronta la mia domanda, che riguarda la scelta del valore inizialmente selezionato. – Antonio