2012-12-20 2 views
6

ich mich umsah habe, fand einige Dinge und jetzt mit zwei Spalten auf eine Combobox steckte in dem Drop-Down-Bereich angezeigt. Ich habe ein Xaml Themen zur Verfügung und die Combobox "Style" ist definiert und funktioniert gut wie erwartet, so dass der Teil in Ordnung ist.WPF Stil Combobox mit zwei Spalten in Drop-Down-

Jetzt habe ich eine Combobox, die ich zwei Werte anzeigen lassen muss, denke an es als Statusabkürzung und Statusname für das Dropdown aus einer DataTable.DefaultView-Bindungsquelle für die Elemente.

Wenn ich

<my:cboStates TextSearch.TextPath="StateAbbrev"> 
    <ComboBox.ItemTemplate> 
    <DataTemplate> 
     <StackPanel Orientation="Horizontal" TextSearch.Text="{Binding Path=StateAbbrev}"> 
     <TextBlock Text="{Binding Path=StateAbbrev}"/> 
     <TextBlock Text="{Binding Path=FullStateName}" Margin="10 0"/> 
     </StackPanel> 
    </DataTemplate> 
    </ComboBox.ItemTemplate> 
</my:cboStates> 

das funktioniert. Nun, wie/wo ich bin stecken ... Nun, ich möchte die gleiche Funktionalität auf etwa 5 verschiedene Formen und alle den gleichen Inhalt anzeigen lassen, und wenn überhaupt geändert (nicht diese, sondern auch für andere mehrspaltigen Comboboxen), Ich möchte das nicht direkt in die XAML-Datei des Formulars schreiben müssen.

Ich hatte gehofft, in einem Thema des Ressourcen Wörterbuch-Datei zu setzen und immer und immer halten die Wiederverwendung nur, dass „Stil“. Macht Sinn. Allerdings, wenn ich tun, und die Bindung an die Datentabelle ist, die nur Ergebnisse, die ich erhalten, wenn sie als eine Art zu tun versuchen, ist die Drop-Down zeigt Werte von

System.Data.DataRowView 
System.Data.DataRowView 
System.Data.DataRowView 
System.Data.DataRowView 

anstelle der tatsächlichen 2 Spalten. Hier ist, was ich im Ressourcenwörterbuch "Thema" habe.

<DataTemplate x:Key="myStateComboTemplate" > 
    <StackPanel Orientation="Horizontal" > 
    <TextBlock Text="{Binding Path=StateAbbrev}"/> 
    <TextBlock Text="{Binding Path=FullStateName}"/> 
    </StackPanel> 
</DataTemplate> 

<Style x:Key="StyleMyStatesCombobox" TargetType="{x:Type ComboBox}" 
    BasedOn="{StaticResource MyOtherWorkingComboBoxStyle}" > 
    <Setter Property="TextSearch.TextPath" Value="{Binding Path=StateAbbrev}" /> 
    <Setter Property="ItemTemplate" Value="{StaticResource myStateComboTemplate}" /> 
</Style> 

Also, wenn ich zwei Instanzen haben meine „cboStates“ Klasse auf dem Formular erstellt, und eine an die explizite Styling zuerst aufgeführt gesetzt, und die zweite auf der Grundlage der „Style“ Einstellung, schlägt der zweite durch zeigt nur die wiederholten System.Data.DataRowView-Einträge, nicht den tatsächlichen Dateninhalt.

Was fehlt mir.

Also, um zu klären, was ich für ... Staaten suchen ... ex Daten

AL Alabama 
AK Alaska 
AZ Arizona 
AR Arkansas 
CA California 
CO Colorado 
CT Connecticut 
DE Delaware 

Ich möchte die Combobox den abgekürzten AL, AK, AZ Anzeige werden, usw. und enger Kombinationsfeld. Dies wird auch der "SelectedValue" bei der Rückkehr sein.

Die tatsächliche Dropdown würde die Daten darstellen, wie oben zeigt sowohl die Abkürzung und die lange Beschreibung des Staates aufgeführt.

Probe der gewünschten Combobox

enter image description here

+0

Gibt es einen Grund, warum Sie die beiden nicht zusammenfügen können? Ich dachte, du könntest immer versuchen, ein Tupel zu benutzen, aber nicht sicher, wie das funktionieren würde. –

+0

@Bob, betrachtet als Tuple, aber dies war nur ein vereinfachtes Beispiel dafür, was in einer Combobox enthalten sein wird, die jeder verstehen könnte. Ich werde tatsächlich eine Vielzahl von ähnlichen Comboboxen haben, die Daten von Tabellen haben und variieren können, also keine festen Werte. Ich wollte die Datenbank nicht abfragen, dann durchschleifen und in ein weiteres Speicher-Tuple stecken, um Schlüssel/Wert/Alt-Wert/Extra-Schlüssel usw. nach Bedarf aus der Ergebnis-Combobox-Präsentation erneut zu analysieren. – DRapp

+0

Was ist mit einem 'Dictionary '? Bindet 'Key' an einen' TextBlock' und 'Value' an den anderen' TextBlock'? Oder gibt es mehr als eine mögliche mehr als zwei Reihen? –

Antwort

0

ENDLICH habe es funktioniert ... und für diejenigen, die versuchen ähnlich. Da ich versuchte, eine standardmäßige "Klassen" -Instanz zu verwenden, die durchgängig verwendet werden kann, aber nicht explizit auf jede Seite XAML referenzieren möchte, musste ein Teil des Stylings während der eigentlichen In-Code-Klasseninstanz behandelt werden.

Da ich nicht genau weiß, wie/wann wo .net Framework baut alle seine Kontrollen, Stil Assignments, etc, war ich frustriert, dass es funktionieren würde, wenn direkt von XAML, aber scheitern, wenn in Code. Also habe ich die Artikelvorlage UND TextSearch.TextPath Werte im Code FORCING. Hier ist ein kurzer Ausschnitt der Klasse

public class myStatesCombo : ComboBox 
{ 
    public myStatesCombo() 
    { 
     Loaded += myAfterLoaded; 
    } 

    protected static DataTable myTableOfStates; 

    public void myAfterLoaded() 
    { 
     if(myTableOfStates == null) 
     myTableOfStates = new DataTable(); 

     CallProcedureToPopulateStates(myTableOfStates); 

     ItemsSource = myTableOfStates.DefaultView; 

     // AFTER the object is created, and all default styles attempted to be set, 
     // FORCE looking for the resource of the "DataTemplate" in the themes.xaml file 
     object tryFindObj = TryFindResource("myStateComboTemplate"); 
     if(tryFindObj is DataTemplate) 
     ItemTemplate = (DataTemplate)tryFindObj; 

     // NOW, the CRITICAL component missed in the source code 
     TextSearch.SetTextPath(this, "StateAbbrev"); 
    } 
} 

Nun, eine besondere Anmerkung.In der Routine, mit der ich die DataTable gefüllt habe, überprüfe ich vorab, ob die Tabelle existiert oder nicht. Beim ersten Mal erstelle ich den Tisch. Wenn ich es wieder füllen muss, wenn ich immer eine "neue DataTable" jedes Mal mache, bläst es die Bindungen der Daten/Elementvorlage weg. Um das zu verhindern, würde ich dann tun

if(myTableOfStates.Rows.Count > 0) 
    myTableOfStates.Rows.Clear(); 

DANN, ich nenne

SQLExecute Anruf aus der Datenbank abzufragen (Dataadapter) und Fill(), um die Datentabelle.

So, jetzt scheint alles korrekt ausgefüllt, Bindungen für die Anzeige und die Textsuche abgeschlossen und bereit zu gehen.