2010-04-27 2 views
5

Erste, faire Warnung: Ich bin ein kompletter Neuling mit C# und WPF.Wie ermittle ich in einer Combobox den markierten Artikel (nicht ausgewählten Artikel)?

Ich habe eine Combobox (editierbar, durchsuchbar) und ich möchte in der Lage sein, die Delete-Taste abzufangen und das aktuell markierte Objekt aus der Liste zu entfernen. Das gesuchte Verhalten ist wie das von MS Outlook bei der Eingabe von E-Mail-Adressen. Wenn Sie ein paar Zeichen eingeben, wird eine Dropdown-Liste mit möglichen Übereinstimmungen angezeigt. Wenn Sie mit den Pfeiltasten zu einem dieser Punkte wechseln und auf Löschen klicken, wird dieser Eintrag endgültig entfernt. Ich möchte das mit einem Eintrag in der Combobox machen.

Hier ist die XAML (vereinfacht):


<ComboBox x:Name="Directory" 
    KeyUp="Directory_KeyUp" 
    IsTextSearchEnabled="True" 
    IsEditable="True" 
    Text="{Binding Path=CurrentDirectory, Mode=TwoWay}" 
    ItemsSource="{Binding Source={x:Static self:Properties.Settings.Default}, 
     Path=DirectoryList, Mode=TwoWay}" /> 

Der Handler ist:


private void Directory_KeyUp(object sender, KeyEventArgs e) 
{ 
    ComboBox box = sender as ComboBox; 
    if (box.IsDropDownOpen && (e.Key == Key.Delete)) 
    { 
     TrimCombobox("DirectoryList", box.HighlightedItem); // won't compile! 
    } 
} 

Wenn das Debugger verwenden, kann ich sehen, box.HighlightedItem den Wert ich will, aber wenn ich versuche, und setzen in diesem Code, schlägt es mit kompilieren:

System.Windows.Controls.ComboBox' does not contain a definition for 'HighlightedItem'...

Also: Wie kann ich auf diesen Wert zugreifen? Beachten Sie, dass der Artikel nicht ausgewählt wurde. Es wird nur hervorgehoben, wenn die Maus darüber schwebt.

Danke für Ihre Hilfe.

Hier ist ein Screenshot, der das Debugger-Display zeigt. Ich schwebte über „Box“, und wenn die einzeilige Zusammenfassung angezeigt wurde, ich schwebte dann über das + Zeichen auf dieses Bild zu erweitern:

alt text http://www.freeimagehosting.net/uploads/2cff35d340.gif

+0

Was genau Sie meinen zu tun, wenn Sie sagen, Sie box.HighlightedItem im Debugger sehen kann? Ist es in einem Uhrenfenster? Es gibt keine öffentliche HighlightedItem-Eigenschaft in ComboBox. –

+0

Ich habe ein Bild am Ende meines Beitrags hinzugefügt. –

Antwort

2

Die hervorgehobene Elementeigenschaft ist ein nicht öffentliches Element, Sie können es also nicht von einer anderen Klasse aufrufen.

alt text http://www.freeimagehosting.net/uploads/1e4dc53cee.png

Ich glaube, Sie brauchen Reflexion zu verwenden, um nicht-öffentliche Mitglieder zu bekommen. Hier ist ein SO Beitrag zum Thema: Access non-public members - ReflectionAttribute

+0

Das scheint es getan zu haben. Vielen Dank! Ich werde den endgültigen Code in eine separate Antwort schreiben, aber Sie mit dem "Gewinner" belohnen. –

+0

Jean, wie bekommst du das Watch-Fenster, um "Nicht-öffentliche Mitglieder" zu trennen? Ich habe dies in VS2008 und VS2010 (Pro Edition) versucht und es tut das nicht. Wenn es so wäre, hätte ich das Problem viel früher herausfinden können. –

+0

Ich fahre mit der Maus über das Objekt, das ich sehen möchte, gehe dann zu Raw View, dann base, dann wird Non Public Members angezeigt. Manchmal gibt es mehrere Ebenen von (Basis), wenn Sie Vererbung verwenden. Ich benutze VS 2010 Ultimate (Immer noch mit freien RC, solange es dauert;)), aber ich denke, es sollte in Pro sein. –

-1

Die Definition von System.Windows.Controls.ComboBox keine Eigenschaft enthält HighlightedItem - das ist warum du Code kompilierst nicht.

Verwenden Sie ein Kombinationsfeld, das von System.Windows.Controls.ComboBox abgeleitet ist? Dann werfen Sie es einfach auf den entsprechenden Typ.

Später Anmerkung: Wenn Sie das markierte Ereignis eines ComboBox this Link zu fangen lesen - es adressiert genau dieses Problem.

+0

Was wäre dieser Typ? Und warum zeigt der Debugger HighlightedItem? –

+0

Wissen Sie nicht, was Sie im Debugger sehen - können Sie kopieren/einfügen welche Variable Sie beobachten und welchen Typ Sie für diese Variable bekommen? – Ando

+0

Bild zum ursprünglichen Beitrag hinzugefügt. Das ist was ich suche. –

0

Sie können einen eigenen DrawItem-Event-Handler erstellen und den Index der Elemente speichern, während sie aktiv gezeichnet werden, und den DrawItemState.Selected (dh den hervorgehobenen) beibehalten.

void Main() 
{ 
    Application.Run(new Form1()); 
} 

public partial class Form1 : Form 
{ 
    ComboBox ComboBox1; 
    string[] ds = new string[]{"Foo", "Bar", "Baz"}; 

    public Form1() 
    { 
     InitializeComboBox(); 
    } 

    private void InitializeComboBox() 
    { 
     ComboBox1 = new ComboBox(); 

     ComboBox1.DataSource = ds; 
     Controls.Add(ComboBox1); 

     ComboBox1.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawVariable; 
     ComboBox1.DrawItem += new DrawItemEventHandler(ComboBox1_DrawItem); 
    } 

    private void ComboBox1_DrawItem(object sender, DrawItemEventArgs e) 
    { 
     e.DrawBackground(); 
     e.Graphics.DrawString(ds[e.Index],ComboBox1.Font,Brushes.Black,e.Bounds); 

     if (e.State == DrawItemState.Selected) 
     { 
      //stores the "HighlightedIndex" in the control's tag field. Change as you see fit. 
      ComboBox1.Tag = e.Index; 
      //Console.WriteLine(e.Index); 
     } 
    } 
} 
+0

Eigentlich benutze ich keine Formulare sondern WPF 3.5 –

7

Unten ist der endgültige Code, wie von Jean Azzopardi die Antwort inspiriert.Die HighlightedItem, die im Debugger wurde zeigt sich war ein nicht-öffentliches Eigentum, und ich bin gezwungen Zugang mit einer Folge von GetType().GetProperty().GetValue()

private void Directory_KeyUp(object sender, KeyEventArgs e) 
{ 
    ComboBox box = sender as ComboBox; 
    if (box.IsDropDownOpen && (e.Key == Key.Delete)) 
    { 
     const BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; 
     PropertyInfo hl = box.GetType().GetProperty("HighlightedItem", flags); 
     if (hl != null) 
     { 
      String hlString = hl.GetValue(sender, null) as String; 
      // TODO: remove from DirectoryList 
     } 
    } 
} 
+1

Ich hatte das gleiche Problem und Ihre Lösung löste es, aber es funktionierte nicht out-of-the-box. Ich musste mir einige Informationen im Debugger ansehen, um herauszufinden, dass die Eigenschaft "HighlightedItem" in meiner Version (.NET 4.0) "HighlightedElement" genannt wurde, also habe ich diese Zeichenfolge im GetProperty() - Aufruf geändert. Der Rest funktioniert einwandfrei. Vielen Dank! –

+1

Ich musste auch die Eigenschaft 'HighlightedElement' verwenden, hatte aber ein anderes Problem, weil ich das datengebundene Element benötigte. Ich konnte den Wert, der von 'GetValue()' zurückgegeben wurde, als 'ComboBoxItem' speichern und dann die' Content' -Eigenschaft verwenden, um das tatsächliche Element zu erhalten, an das das 'HighlightedElement' gebunden war. – Kidiskidvogingogin