2010-04-27 17 views
5

Primero, advertencia justa: soy un novato completo con C# y WPF.En un cuadro combinado, ¿cómo determino el elemento resaltado (elemento no seleccionado)?

Tengo un cuadro combinado (editable, con capacidad de búsqueda) y me gustaría poder interceptar la tecla Eliminar y eliminar el elemento actualmente resaltado de la lista. El comportamiento que estoy buscando es como el de MS Outlook al ingresar direcciones de correo electrónico. Cuando da unos pocos caracteres, se muestra una lista desplegable de posibles coincidencias. Si se mueve a uno de estos (con las teclas de flecha) y presiona Eliminar, esa entrada se elimina permanentemente. Quiero hacer eso con una entrada en el cuadro combinado.

Aquí es el XAML (simplificada):


<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}" /> 

El controlador es:


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

Cuando se utiliza el depurador, puedo ver box.HighlightedItem tiene el valor que quiero, pero cuando intento y poner en ese código, que falla al compilar con:

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

Entonces, ¿cómo accedo a ese valor? Tenga en cuenta que el artículo tiene no seleccionado. Simplemente se resalta cuando el mouse se cierne sobre él.

Gracias por su ayuda.

Aquí hay una captura de pantalla que muestra la pantalla del depurador. Yo flotaba sobre "caja" y cuando se visualiza el resumen de una línea, entonces se movía sobre el carbón + para expandir a esta imagen:

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

+0

¿Qué es exactamente a qué se refiere cuando dice que puede ver box.HighlightedItem en el depurador? ¿Está en una ventana de observación? No hay una propiedad pública HighlightedItem en ComboBox. –

+0

Agregué una foto al final de mi publicación. –

Respuesta

2

La propiedad de Elemento resaltado es un miembro no público, por lo que no puede llamar desde otra clase.

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

creo que es necesario utilizar la reflexión para llegar a los miembros que no son públicas. Aquí hay una publicación SO sobre el tema: Access non-public members - ReflectionAttribute

+0

Eso parece haberlo hecho. ¡Gracias! Pondré el código final en una respuesta separada, pero le doy el crédito del "ganador". –

+0

Jean, ¿cómo se obtiene la ventana Inspección para separar "Miembros no públicos"? He intentado esto en VS2008 y VS2010 (edición Pro) y no hace eso. Si lo hubiera hecho, podría haber resuelto el problema mucho antes. –

+0

Hago clic sobre el elemento que quiero ver, luego voy a Vista sin formato, luego a base y, a continuación, aparecen los Miembros no públicos. A veces hay múltiples niveles de (base) si está usando herencia. Estoy usando VS 2010 Ultimate (todavía usando RC gratis mientras dure;)), pero creo que debería estar en Pro. –

-1

La definición de System.Windows.Controls.ComboBox no contiene una propiedad HighlightedItem - que es por qué tu código no se compila

¿Está utilizando un cuadro combinado derivado de System.Windows.Controls.ComboBox? Luego simplemente transfiéralo al tipo apropiado.

Nota posterior: Si se desea capturar el evento resaltado de un cuadro combinado leer this enlace - se dirige exactamente este problema.

+0

¿Qué sería ese tipo? ¿Y por qué el depurador muestra HighlightedItem? –

+0

No sé lo que está viendo en el depurador: ¿puede copiar/pegar qué variable está viendo y qué tipo obtiene para esa variable? – Ando

+0

Imagen añadida a la publicación original. Esto es lo que estoy buscando. –

0

Puede crear su propio manejador de eventos DrawItem y guardar el índice de los elementos a medida que se dibujan activamente y mantener el DrawItemState.Selected (es decir, el resaltado).

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

En realidad, no estoy utilizando formularios, sino WPF 3.5 –

7

A continuación se muestra el código final, inspirado en la respuesta de Jean Azzopardi.El HighlightedItem que fue apareciendo en el depurador era una propiedad no pública y yo estoy forzando el acceso con una secuencia de 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

Tuve el mismo problema y tu solución lo resolvió, pero no funcionó de inmediato. Tuve que buscar cierta información en el depurador para encontrar que la propiedad "HighlightedItem" se llamaba "HighlightedElement" en mi versión (.NET 4.0), así que cambié esa cadena en la llamada a GetProperty(). El resto funciona a la perfección. ¡Gracias! –

+1

También tuve que usar la propiedad 'HighlightedElement', pero tenía otro problema porque necesitaba el elemento de datos. Pude almacenar el valor devuelto por 'GetValue()' como 'ComboBoxItem' y luego usar la propiedad' Content' dentro de eso para obtener el elemento real al que estaba sujeto 'HighlightedElement'. – Kidiskidvogingogin

Cuestiones relacionadas