2009-02-26 7 views
15

Ich versuche, eine WPF Combobox arbeiten (innerhalb der WPFToolkit Datagrid), und ich habe Probleme, alle Teile richtig ausgerichtet. Ich verwende Linq to Entities, und ich bin die Gesamtdatacontext auf die Ergebnisse einer Linq-Abfrage einstellen:WPF ComboBox nicht Update-Quelle


private void LoadDonationGrid() 
{ 
    donationGrid.ItemsSource = from donations in entities.Donation 
        .Include("Family") 
        .Include("PledgeYear") 
        .Include("DonationPurpose") 
       from donationPurposes in entities.DonationPurpose 
       select new { donations, donationPurposes }; 
} 

Ich habe auch eine Seite Eigenschaft in meinem Code-behind, die die Itemssource für die Combobox bietet:


private IEnumerable donationPurposeList; 
public IEnumerable DonationPurposeList 
{ 
    get 
    { 
     if (donationPurposeList == null) 
     { 
      donationPurposeList = from dp in entities.DonationPurpose 
            select dp; 
     } 
     return donationPurposeList.ToList(); 
    } 
} 

die XAML für die Combobox sieht wie folgt aus:

<tk:DataGridTemplateColumn Header="Purpose"> 
    <tk:DataGridTemplateColumn.CellTemplate> 
     <DataTemplate> 
      <TextBlock Text="{Binding Path=donations.DonationPurpose.Description, Mode=TwoWay}" /> 
     </DataTemplate> 
    </tk:DataGridTemplateColumn.CellTemplate> 
    <tk:DataGridTemplateColumn.CellEditingTemplate> 
     <DataTemplate> 
      <ComboBox Name="cboDonationPurpose" 
       SelectedValue="{Binding Path=donations.DonationPurposeID, Mode=TwoWay}" 
       ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type Page},Mode=FindAncestor},Path=DonationPurposeList}"         
       DisplayMemberPath="Description" 
       SelectedValuePath="DonationPurposeID" 
         /> 
     </DataTemplate> 
    </tk:DataGridTemplateColumn.CellEditingTemplate> 
</tk:DataGridTemplateColumn> 

Und alles scheint richtig zu funktionieren, dh die entsprechenden Werte in der ComboBox angezeigt werden, bis hin zu dem Punkt, wh Der Fokus verlässt die ComboBox. An diesem Punkt wird der angezeigte Wert auf den ursprünglichen Wert und nicht auf den neu ausgewählten Wert zurückgesetzt. Ich habe versucht, SelectedItem anstelle von SelectedValue zu verwenden, aber das endet damit, dass der ausgewählte Wert nicht in der ComboBox angezeigt wird. Ich bin irgendwie verwirrt: Es scheint, als ob dieses Bit funktionieren sollte.

Bearbeitet 02.03.09: Ich bin immer noch rätselhaft darüber. Ich sollte beachten, dass in meinem Datagrid alle einfachen Datenspalten (z. B. "DataGridTextColumn") die zugrunde liegende Datenquelle genau so aktualisieren, wie Sie es erwarten. Aber jede Aktualisierung auf meine Spaltenvorlagen ("DataGridTemplateColumn") oder ComboBox-Spalten ("DataGridComboBoxColumn") funktioniert nicht: Die zugrunde liegende Datenquelle wird nie aktualisiert. Sicherlich haben andere Leute versucht, das WPF.Toolkit-Datagrid zu verwenden und dieses Szenario zum Laufen zu bringen - aber ich habe mir den ganzen Beispielcode angesehen, und ich mache im Grunde, was es zu tun vorgibt (innerhalb der Grenzen meines Lösung), also kratze ich mich am Kopf, warum das nicht funktioniert.

Irgendwelche Gedanken?

Antwort

20

Ich hatte ein ähnliches Problem (an dem ich Tage der Frustration verbrachte), und ich fand, dass die Änderung der UpdateSourceTrigger auf der SelectedValue Bindung zu PropertyChanged es behoben. Ich weiß nicht warum, aber für mich wurde die Datenquelle nicht aktualisiert, bis ich diese Änderung vorgenommen habe.

<ComboBox 
    ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UpdateTypesManager:MainWindow}}, Path=CardinalityTypes}" 
    DisplayMemberPath="CardinalityType" 
    SelectedValue="{Binding CardinalityTypeId, UpdateSourceTrigger=PropertyChanged}" 
    SelectedValuePath="Id" /> 
+0

Ich hatte genau das gleiche Problem. Ich habe stundenlang damit zu tun gehabt. Ich habe die Bindung an TwoWay geändert und versucht, eine ganze Reihe anderer Dinge zu ändern. [MSDN] (http://msdn.microsoft.com/en-us/library/system.windows.data.binding.updatesourcetrigger.aspx) scheint das zu sein Geben Sie an, dass der Standardwert in Fällen wie Text auf LostFocus gesetzt ist. –

+0

Eigentlich ist es nicht LostFocus für mich, wenn ich eine Textbox benutze. Wenn Sie es auf PropertyChanged setzen, wird dies jedoch behoben. – tcables

+0

Ausgezeichnet !! Samething funktioniert auch für SelectedItem-Bindung – Adarsha

5

Ich konnte das funktioniert. Aber ich habe die Dinge etwas anders gemacht.

  1. Ich erstellte ein ViewModel, um als ein Vertrag mit der Ansicht zu fungieren.
  2. gebunden ich zum ComboBox.SelectedItem Eigentum statt ComboBox.SelectedValue Immobilien

Da ich nicht wusste, was Ihre Datenquelle wurde ich aus eigener das grundlegende Problem zu simulieren: richtig ein comboBox klemmt innerhalb eines WPF DataGrids. Hier

ist die Zusammensetzung meiner Ansicht Modell:

public class RootViewModel 
{ 
    public List<State> USStates { get; set; } 
    public List<Customer> Customers { get; set; } 

    public ViewModel() 
    { 
     Customers = new List<Customer>(); 
     Customers.Add(new Customer() { FirstName = "John", LastName = "Smith", State = new State() { ShortName = "IL" } }); 
     Customers.Add(new Customer() { FirstName = "John", LastName = "Doe", State = new State() { ShortName = "OH" } }); 
     Customers.Add(new Customer() { FirstName = "Sally", LastName = "Smith", State = new State() { ShortName = "IN" } }); 

     USStates = new List<State>(); 
     USStates.Add(new State() { ShortName = "OH" }); 
     USStates.Add(new State() { ShortName = "IL" }); 
     USStates.Add(new State() { ShortName = "IN" }); 
    } 
} 

public class Customer 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public State State { get; set; } 
} 

public class State 
{ 
    public string ShortName { get; set; } 

    public State() 
    { 
     ShortName = string.Empty; 
    } 

    public override bool Equals(object obj) 
    { 
     if (obj is State) 
     { 
      State otherState = obj as State; 
      return ShortName.Equals(otherState.ShortName); 
     } 
     else 
     { 
      return false; 
     } 
    } 
} 

Bevor wir beginnen, stelle ich die Datacontext von meinem Fenster eine Instanz meines richtig konstruiert RootViewModel zu sein.

<tk:DataGrid ItemsSource="{Binding Customers}" AutoGenerateColumns="False"> 
      <tk:DataGrid.Columns> 
       <tk:DataGridTemplateColumn Header="State"> 
        <tk:DataGridTemplateColumn.CellTemplate> 
         <DataTemplate> 
          <TextBlock Text="{Binding Path=State.ShortName, Mode=TwoWay}" /> 
         </DataTemplate> 
        </tk:DataGridTemplateColumn.CellTemplate> 
        <tk:DataGridTemplateColumn.CellEditingTemplate> 
         <DataTemplate> 
          <ComboBox 
           x:Name="cboDonationPurpose" 
           SelectedItem="{Binding Path=State, Mode=TwoWay}" 
           ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window},Mode=FindAncestor}, Path=DataContext.USStates}" 
           DisplayMemberPath="ShortName" 
           SelectedValuePath="ShortName" /> 
         </DataTemplate> 
        </tk:DataGridTemplateColumn.CellEditingTemplate> 
       </tk:DataGridTemplateColumn> 
      </tk:DataGrid.Columns> 
     </tk:DataGrid> 

Damit die SelectedItem richtig binden, ich sicherstellen müssen, dass ich die Equals-Methode auf meiner Einheit außer Kraft gesetzt haben, da unter der Haube, ist diese Methode mit WPF zu bestimmen, wer die SelectedItem ist oder nicht. Ich glaube, das war von Anfang an das Problem, das Sie dazu brachte, an SelectedValue statt an SelectedItem zu binden.

0

Sie benötigen

IsSynchronizedWithCurrentItem = "True" 

in XAML hinzuzufügen.

So einfach ist das ...

+2

Die Einstellung auf "False" hat ein ähnliches Problem gelöst. –