2009-12-03 10 views
7

Tengo mi DataContext configurado en un objeto Libro. El libro tiene propiedades: Título, Categoría.¿Cómo selecciono un elemento en mi WPF ComboBox basado en mi enlace de datos?

Tengo un CollectionViewSource "categoryList" que contiene una lista de categorías.

Pregunta: ¿Cómo selecciono Categoría del libro en este cuadro combinado?

<TextBox Text="{Binding Path=Title}"/> 

<ComboBox SelectedValuePath="Id" 
      SelectedValue="{Binding Path=Category.Id}" 
      SelectedItem="{Binding Path=Category}" 
      ItemsSource="{Binding Source = {StaticResource categoryList}}" 
      DisplayMemberPath="Name" /> 

El código anterior muestra el título del libro correctamente y luego muestra la lista de nombres de categorías en el cuadro combinado. Pero no selecciona la Categoría del Libro. En su lugar, simplemente selecciona el primer elemento en la lista.

Respuesta

7

Estás vinculando demasiado; solo necesita configurar SelectedValue y SelectedValuePath, o SelectedItem. En este caso, parece que en realidad estás tratando de vincular a un objeto específico. Si usted está tratando de tener la ComboBox establecer la propiedad Category en su Book y la corriente Book objeto en realidad tiene una referencia a una instancia de Category que está en categoryList, entonces usted debe utilizar el SelectedItem vinculante y eliminar los enlaces para SelectedValue y SelectedValuePath.

Editar

Para ampliar un poco sobre cómo se hace esto, SelectedValue está diseñado para ser utilizado cuando se tiene una pieza común de información para vincular su artículo enlazado con una propiedad en el origen de la lista. Por ejemplo, digamos que tengo una clase Book con una propiedad CategoryID.

public class Book 
{ 
    public string CategoryID { get; set; } 
    public string Title { get; set; } 
} 

public class CategoryID 
{ 
    public string ID { get; set; } 
    public string Name { get; set; } 
} 

En este caso, se debe hacer:

<ComboBox SelectedValue = "{Binding CategoryID}" 
      SelectedValuePath = "ID" 
      DisplayMemberPath = "Name" /> 

SelectedItem, por el contrario, es para cuando la instancia de cota tiene una referencia real a (o, más precisamente, un objeto que es equivalente a) un elemento en la lista encuadernada. Por lo tanto, vamos a suponer que la clase Book realmente se ve así:

public class Book 
{ 
    public Category Category { get; set; } 
    public string Title { get; set; } 
} 

En este caso, se debe hacer:

<ComboBox SelectedItem = "{Binding Category}" 
      DisplayMemberPath = "Name" /> 

Pero es muy importante tener en cuenta que esto no funcionará a menos que la clase Book tiene una referencia a la misma instancia de Category que la que tiene en la lista. Si las referencias son diferentes (incluso si los valores en las clases son iguales), entonces esto no funcionará, ya que el ComboBox no podrá encontrar el Category al que se hace referencia en el Book en la lista.

El problema real con la forma en que lo estaba enlazando (vinculando a Category.ID) es que está mezclando los esquemas. Usted tiene una referencia, pero está tratando de enlazar la clave en su lugar. Todo lo que hará es intentar establecer el valor en su referencia, , no intentará cambiar la referencia en su clase.

+0

Lo sentimos sí, sólo un poco de lo tiró todo por ahí. :) SelectedValue + SelectedValuePath no funciona. Tampoco lo hace SelectedItem. O incluso el SelectedItem + SelectedValuePath como Doug muestra a continuación. Ergh. Creo que las categorías de la categoryList están interfiriendo de alguna manera con mi capacidad para obtener la Categoría del Libro (si solo me enlace directamente a Category.Name en un campo de texto debajo obtendré el valor incorrecto. Pero si hago un comentario sobre el enlace a categoryList, el valor es correcto) Voy a probar su sugerencia de depuración. Gracias. –

+0

Esto fue realmente útil, gracias. Aunque, curiosamente, también tuve que hacer isSynchronizedWithCurrentItem = True para que funcione (estoy usando SelectedItem como se muestra arriba). No entendiendo esa parte. –

+0

@Abby: ¿Está vinculando esta lista de objetos 'Categoría' a cualquier otra fuente de datos? Si es así, eso tendría sentido. –

2

de describir en lo que Adam código de hablar de:

<ComboBox 
    SelectedValuePath="Id" 
    SelectedItem="{Binding Path=Category}" 
    ItemsSource="{Binding Source={StaticResource categoryList}}" 
    DisplayMemberPath="Name" /> 

es probablemente más apropiado. En general, es mejor tratar SelectedValue como de solo lectura, y usar SelectedItem para elegir el elemento que desea seleccionar. Cuando enlaza el SelectedItem con el Category del libro, establece automáticamente la propiedad SelectedValue para usted de todos modos.

Si eso todavía no funciona, es posible que desee comprobar que su enlace a Category está funcionando correctamente. En particular, agregar un DebugConverter funciona bien para garantizar que el valor que espera sea consolidado. You can see the use of DebugConverter is the answer to this question.

-Doug

+0

Esto es cierto (aunque en este caso 'SelectedValuePath' no es obligatorio) solo si el objeto enlazado comparte la misma referencia con el elemento en la lista. Si son referencias diferentes pero comparten una clave común, entonces esto es incorrecto. –

+0

WOW, gracias por la idea de depuración: eso es increíble. Lo usé y descubrí que de alguna manera está configurando mi valor de Categoría (en el ConvertBack) en el primer elemento de la lista ComboBox. Ahora estoy realmente confundido. Pero con una herramienta mejor al menos, gracias. –

+0

y esto (solo para hacer un seguimiento) se solucionó agregando IsSynchronizedWithCurrentItem = True, aunque no tengo claro por qué. –

Cuestiones relacionadas