2009-02-02 7 views
8

Ich möchte meine ComboBox in XAML an meine List Sammlung von benutzerdefinierten Objekten im Code hinter zu binden.WPF: ComboBox zeigt "(Namespace). (Klassenname)" anstelle von Daten

Derzeit die ComboBox Listen für jeden Eintrag dpwpf.Contact, die meine {namespace}.{classname} ist.

Was muss ich in den XAML eingeben, um es aufzulisten, z. Nachname + Vorname?

Ich weiß, es ist so etwas wie {Binding Path=... Value=...}, aber ich kann es nicht bekommen.

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> 

-Code Behind:

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

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

Antwort:

<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

Mögliche Duplikat [WPF IsEditable = true ComboBox gefüllt mit Objekten zeigt die ToString() als das ausgewählte Element] (https://stackoverflow.com/questions/1844156/wpf- iseditable-true-combobox-filled-with-objects-zeigt-the-tostring-as-the) –

Antwort

7

können Sie die ToString Methode von Contact außer Kraft setzen, oder Sie können eine DataTemplate in WPF definieren.

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> 

Auf diese Weise können Sie festlegen, wie ein Contact Objekt irgendwo im Fenster angezeigt. Wenn Sie dies auf die ComboBox begrenzen möchten, können Sie die DataTemplate nur zu den ComboBox Ressourcen hinzufügen.

Siehe auch What does "{Binding}" mean? von Bea Stöllnitz

+0

Wow, ich werde das einlassen müssen, Sie haben ein StackPanel in einem ComboBoxItem. Der geschriebene Antwortcode funktioniert also oben, aber ich sehe die Verbindung zwischen meiner ComboBox und der DataTemplate nicht, ich erwarte, dass die DataTemplate einen Namen hat und die ComboBox darauf verweist. –

+0

Die Combobox zeigt Kontaktobjekte. WPF durchsucht die visuelle Struktur nach einem DataTemplate, das Kontakte anzeigt, und verwendet diese Vorlage. Wenn keine Vorlage vorhanden ist, wird standardmäßig ToString verwendet. Es gibt keine direkte Verbindung außer über das Kontaktobjekt. –

+0

Das ist die Schönheit von WPF. Sie definieren eine Art, ein Datenobjekt zu zeigen, und dann, wo das Objekt auftaucht, wird die Vorlage verwendet, um es anzuzeigen. –

2

Sie brauchen Display = "theValue"

Sie diese hinzufügen können, verwenden, in der XAML oder in der CLR beachten Sie auch Ihre Bindung in cose und nicht durch den XAML. Ich denke, das bezieht sich auf eine Ihrer früheren Fragen. , die die Bindung durch Object implementiert dieses Beispiel verwenden und die DisplayMemeber = „memeber“ in dem XAML

HTH, Eric,

+0

ja, das wird funktionieren, aber ich möchte in der Lage sein, den Text statt der Combobox Element, z Nachname + "" + Vorname –

+0

Hallo Edward, Entschuldigung, es hat so lange gedauert. Sie haben ein paar Möglichkeiten, um das Problem anzugehen. 1) füge eine Eigenschaft FullName hinzu, die this.lastname + "," + this.firstname zurückgibt. und benutze es als das deiplay-Mitglied. HH, Eric – user61477

+0

2) Verwenden Sie einen IValueConverter, um den angezeigten Wert zu konvertieren. Sie können ihn als statische Ressource im XAML verwenden und die XML-Eigenschaft Converter hinzufügen. – user61477

4

Was der Bindungsmechanismus tut ruft ToString() auf der Art hinzufügen, dass wird gebunden. Weil ich denke, dass Sie nicht ToString() überschreiben, wird es nur so der namespace.type statt etwas Nützliches.

Wie rebellious sagt, können Sie DisplayMember verwenden, um der Bindung mitzuteilen, eine Eigenschaft dieses Namens für den Anzeigewert zu verwenden, oder Sie können ToString() wie folgt überschreiben, um Ihre benutzerdefinierte Eigenschaft anzuzeigen.

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

das ist nett, aber ich könnte andere Steuerelemente haben, die anders überschreiben möchten, und soweit ich verstehe, bekomme ich nur eine Überschreibung. –

6

Gerade dieses Add in Sie ComboBox-Tag (XAML-Code)

TextSearch.TextPath ="Title" 

ToString() Modifikation alle zukünftigen Fälle betrifft Sie es brauchen, ich empfehle Ihnen nicht zu tun Das.

Sehen Sie das Beispiel: http://simplesample.site90.com/wpf_combobox.php

+0

Ich wusste, dass es eine Eigenschaft wie 'TextSearch.TextPath' ist, aber Junge ist es schwer, die richtige Antwort unter denen zu finden, die' ToString's und 'DisplayMemberPath' vorschlagen ... Danke! – Gman