2009-02-02 6 views
8

Quiero obtener mi ComboBox en XAML para enlazar a mi colección List de objetos personalizados en el código subyacente.WPF: ComboBox muestra "(namespace). (Classname)" en lugar de datos

Actualmente el ComboBox listas para cada entrada dpwpf.Contact que es mi {namespace}.{classname}.

¿Qué debo poner en el XAML para indicarle que haga una lista, p. Apellido + Nombre?

Sé que es algo así como {Binding Path=... Value=...} pero no puedo conseguirlo.

XAML:

<Window x:Class="dpwpf.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="300" Width="300"> 
    <StackPanel> 
     <StackPanel> 
      <TextBlock Text="Select the contact:"/> 
      <ComboBox Name="theContactList"/> 
     </StackPanel> 
    </StackPanel> 
</Window> 

código subyacente:

namespace dpwpf 
{ 
    public partial class Window1 : Window 
    { 
     public Window1() 
     { 
      InitializeComponent(); 

      StoreDB db = new StoreDB(); 
      List<Contact> contacts = db.GetContacts() 
      theContactList.ItemsSource = contacts.ToList(); 
     } 
    } 
} 

Respuesta:

<Window x:Class="dpwpf.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="300" Width="300" 
    xmlns:local="clr-namespace:dpwpf"> 

    <Window.Resources> 
     <DataTemplate DataType="{x:Type local:Contact}"> 
      <StackPanel Orientation="Horizontal"> 
       <TextBlock Text="{Binding LastName}"/> 
       <TextBlock Text=" "/> 
       <TextBlock Text="{Binding FirstName}"/> 
      </StackPanel> 
     </DataTemplate> 
    </Window.Resources> 

    <StackPanel> 
     <StackPanel Margin="10"> 
      <TextBlock Text="Contact Name:" Foreground="#555"/> 
      <TextBox Name="theName"/> 
     </StackPanel> 
     <StackPanel> 
      <TextBlock Text="Select the contact:"/> 
      <ComboBox Name="theContactList"/> 
     </StackPanel> 
    </StackPanel> 
</Window> 
+0

posible duplicado de [WPF IsEditable = true ComboBox lleno de objetos muestra el ToString() como el elemento seleccionado] (https://stackoverflow.com/questions/1844156/wpf- iseditable-true-combobox-filled-with-objects-displays-the-tostring-as-the) –

Respuesta

7

Puede reemplazar el método de ToStringContact, o puede definir un DataTemplate en WPF.

xmlns:dpwpf="... namespace of dpwpf" 

<Window.Resources> 
    <DataTemplate DataType="{x:Type dpwpf:Contact}"> 
     <StackPanel Orientation="Horizontal"> 
      <TextBlock Text="{Binding LastName}"> 
      <TextBlock Text=" "> 
      <TextBlock Text="{Binding FirstName}"> 
     </StackPanel> 
    </DataTemplate> 
</Window.Resources> 

Esto le permite definir cómo aparecerá un objeto Contact en cualquier lugar de la ventana. Si desea limitar esto al ComboBox, puede agregar DataTemplate solo a los recursos ComboBox.

Ver también What does "{Binding}" mean? Bea Stollnitz

+0

wow, voy a tener que dejar que eso se hunda, tienes un StackPanel funcionando dentro de un ComboBoxItem. Entonces, el código de respuesta publicado funciona arriba, pero no veo la conexión entre mi ComboBox y DataTemplate, estoy esperando que DataTemplate tenga un nombre y ComboBox se refiera a él. –

+0

El cuadro combinado muestra objetos de contacto. Entonces, WPF busca en el árbol visual una DataTemplate que muestra Contactos y usa esa plantilla. Si no hay una plantilla, se usa de forma predeterminada ToString. No hay conexión directa excepto a través del objeto de contacto. –

+0

Esta es la belleza de WPF. Define una forma de mostrar un objeto de datos, y luego, donde sea que aparezca ese objeto, la plantilla se usa para mostrarlo. –

2

es necesario utilizar DisplayMember = "ElValor"

puede agregar a este en el XAML o en el CLR también tenga en cuenta su enlace en cose y no a través de XAML. Creo que esto se relaciona con una pregunta previa tuya. que implementa la unión a través ObjectDataProvider usar ese ejemplo y agregue el DisplayMemeber = "memeber" en el XAML

HTH, Eric,

+0

sí, esto funcionará, pero quiero poder formatear el texto en lugar del elemento del cuadro combinado, por ejemplo lastname + "" + firstname –

+0

Hola Edward, lo siento, me tomó tanto tiempo. tiene un par de maneras de abordar el problema. 1) agregue una propiedad FullName que devuelve this.lastname + "," + this.firstname. y usarlo como el miembro deisplay. HH, Eric – user61477

+0

2) utilice un IValueConverter para convertir el vaule desplegado, puede utilizarlo como un recurso estático en el XAML y agregar el Convert XML propert. – user61477

4

Lo que el mecanismo de unión está haciendo es llamar ToString() del tipo que está siendo atado. Debido a que supongo que no está reemplazando a ToString(), solo lo hará el namespace.type en lugar de algo útil.

Como dice rebelde, puede usar DisplayMember para indicar al enlace que use una propiedad de ese nombre para el valor de visualización o puede anular ToString() como se muestra a continuación para mostrar su propiedad personalizada.

public void Contact 
{ 
public string FirstName { get; set; } 
public override string ToString() 
{ 
    return FirstName; 
} 
} 
+1

esto es bueno, pero es posible que tenga otros controles que quiera sobrescribir de manera diferente, y por lo que yo entiendo, solo obtengo una anulación. –

6

Sólo añadir que esto en la etiqueta ComboBox (código XAML)

TextSearch.TextPath ="Title" 

ToString() modificación afecta a todos los casos futuros que lo necesite, no te recomiendo que hacer ese.

Ver ese ejemplo: http://simplesample.site90.com/wpf_combobox.php

+0

Sabía que es una propiedad como 'TextSearch.TextPath', pero es difícil encontrar la respuesta correcta entre aquellos que sugieren' ToString's y 'DisplayMemberPath's ... ¡Gracias! – Gman

Cuestiones relacionadas