2009-02-26 16 views
15

Próbuję uzyskać działanie combobox WPF (wewnątrz WPFToolkit Datagrid) i mam problem z wyrównaniem wszystkich elementów. Używam Linq do podmiotów, a ja ustalaniu ogólnej datacontext do wyników kwerendy LINQ:WPF ComboBox nie aktualizuje źródła


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 }; 
} 

Mam też właściwość strony w moim kodu źródłowego, który zapewnia ItemsSource do combobox:


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

XAML dla combobox wygląda następująco:

<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> 

I wszystko wydaje się działać poprawnie, to znaczy, odpowiednie wartości są wyświetlane w ComboBox, aż do punktu WH ere focus opuszcza ComboBox. W tym momencie wyświetlana wartość powraca do pierwotnej wartości, a nie do nowo wybranej wartości. Próbowałem używać SelectedItem zamiast SelectedValue, ale kończy się na wybranej wartości nie pokazano w ComboBox. Jestem trochę zdezorientowany: wygląda na to, że ten kawałek powinien działać.

Edytowane 3/2/09: Nadal zastanawiam się nad tym. Należy zauważyć, że w moim datagrid, wszystkie proste kolumny danych (np. "DataGridTextColumn") aktualizują podstawowe źródło danych tak, jak można się spodziewać. Jednak żadna aktualizacja żadnej z kolumn szablonowych ("DataGridTemplateColumn") ani kolumn ComboBox ("DataGridComboBoxColumn") nie działa: źródłowe źródło danych nigdy nie zostanie zaktualizowane. Z pewnością inni próbowali użyć datagridu WPF.Toolkit i stworzyli ten scenariusz - ale przyjrzałem się wszystkiemu przykładowemu kodowi i robię zasadniczo to, co ma robić (w ramach ograniczeń mojego rozwiązanie), więc drapię się po głowie, dlaczego to nie działa.

Jakieś myśli?

Odpowiedz

20

Miałem podobny problem (na którym spędziłem wiele dni frustracji) i stwierdziłem, że zmiana UpdateSourceTrigger na SelectedValue związania z PropertyChanged naprawiła to. Nie wiem dlaczego, ale dla mnie źródło danych nie było aktualizowane, dopóki nie wprowadziłem tej zmiany.

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

Miałem dokładnie ten sam problem. Robiłem sobie z tym pogawędkę przez wiele godzin. Zmieniłem powiązanie z TwoWay, próbowałem zmienić cały szereg innych rzeczy. Wydaje się, że [MSDN] (http://msdn.microsoft.com/en-us/library/system.windows.data.binding.updatesourcetrigger.aspx) wskazuje, że domyślnym ustawieniem jest LostFocus w przypadkach takich jak Text. –

+0

W rzeczywistości nie domyślam się LostFocus dla mnie, gdy używam pola tekstowego. Ustawienie tego na PropertyChanged rozwiązuje to jednak. – tcables

+0

Doskonały !! Powiązanie działa nawet w przypadku powiązania SelectedItem. – Adarsha

5

Udało mi się to zadziałać. Ale ustawiłem trochę inaczej.

  1. Stworzyłem ViewModel, aby działał jako kontrakt z View.
  2. I związany z ComboBox.SelectedItem Własności zamiast ComboBox.SelectedValue Property

Ponieważ nie wiedział, co źródło danych została wymyśliłem własną rękę, aby symulować podstawowy problem: mający powiązania combobox poprawnie w ramach DataGrid WPF.

Oto skład moim zdaniem Model:

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; 
     } 
    } 
} 

Zanim zaczniemy, ustawić DataContext moim oknem być instancją moim prawidłowo skonstruowanej RootViewModel.

<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> 

W celu umożliwienia prawidłowego związania selectedItem muszę zapewnić, że mam nadpisane metody równa się na moim podmiot ponieważ pod maską, WPF jest za pomocą tej metody, aby ustalić, kto jest SelectedItem czy nie. Myślę, że był to zasadniczo twój problem od samego początku, który spowodował, że spróbowałeś powiązać SelectedValue zamiast SelectedItem.

0

Trzeba dodać

IsSynchronizedWithCurrentItem = "True" 

w Xaml.

To takie proste ...

+2

Ustawienie na "False" rozwiązało podobny problem. –

Powiązane problemy