2016-08-16 24 views
6

Mam kolumnę DataTemplate z, które są powiązane z 2 właściwościami. Gdy dane w tych kontroli jest zmieniana tylko ostatnia kontrola jest aktualizowanyTylko ostatnia kontrolka w kolumnie Szablon danych aktualizowana

 <sdk:DataGridTemplateColumn Width="300" CanUserReorder="False" >    
     <sdk:DataGridTemplateColumn.CellTemplate> 
       <DataTemplate> 
       <Grid MouseRightButtonDown="ActionsGrid_MouseRightButtonDown" Width="300" Height="40" MouseLeftButtonDown="ActionsGrid_MouseLeftButtonDown"> 
         <StackPanel Orientation="Horizontal"> 
          <TextBlock VerticalAlignment="Stretch" Width="100" Text="{Binding Start, Converter={StaticResource DateConverter}}" 
             Padding="2" HorizontalAlignment="Center" /> 
          <TextBlock VerticalAlignment="Stretch" Width="100" Text="{Binding Due, Converter={StaticResource DateConverter}}" 
             Padding="2" HorizontalAlignment="Center" /> 
         </StackPanel> 
        </Grid> 
       </DataTemplate>             
      </sdk:DataGridTemplateColumn.CellTemplate> 
    <sdk:DataGridTemplateColumn.CellEditingTemplate> 
       <DataTemplate> 
        <StackPanel Orientation="Horizontal"> 
         <sdk:DatePicker VerticalAlignment="Top" Width="100" SelectedDate="{Binding Start, Mode=TwoWay,}" Padding="2" /> 
         <sdk:DatePicker VerticalAlignment="Top" Width="100" SelectedDate="{Binding Due, Mode=TwoWay, ValidatesOnDataErrors=True}" Padding="2" /> 
        </StackPanel> 
       </DataTemplate> 
    </sdk:DataGridTemplateColumn.CellEditingTemplate> 
    </sdk:DataGridTemplateColumn> 

W tym przypadku, jeśli mogę zaktualizować zarówno data rozpoczęcia i tylko ze względu zostanie zaktualizowany. Także wiążące działa dobrze, ponieważ jeśli mogę umieścić punkt przerwania na start w klasie modelu to dostanie, ale wartość przekazywana jest oryginalna wartość start

EDIT 1

Po pewnym debugowania I okazało się, że jeśli Mam tylko jedną kontrolę wewnątrz mojego DataTemplate działa poprawnie. Również Kiedy zmieniam datę Punkt przerwany jest natychmiastowy. Ale jeśli mam więcej niż jedną kontrolę, punkt przerwania nie zostanie trafiony, dopóki nie ustawię ostrości poza kolumną, a wtedy tylko ostatnie wiązanie działa.

EDIT 2

Po pewnym mroe debugowania zauważyłem, że to będzie działać dobrze, jeśli mogę użyć CellTemplate tylko i wyrzucić komórkę EditTemplate

 <sdk:DataGridTemplateColumn Width="300" CanUserReorder="False" >    
      <sdk:DataGridTemplateColumn.CellTemplate> 
       <DataTemplate> 
        <StackPanel Orientation="Horizontal"> 
         <sdk:DatePicker VerticalAlignment="Top" Width="100" SelectedDate="{Binding Start, Mode=TwoWay,}" Padding="2" /> 
         <sdk:DatePicker VerticalAlignment="Top" Width="100" SelectedDate="{Binding Due, Mode=TwoWay, ValidatesOnDataErrors=True}" Padding="2" /> 
        </StackPanel> 
       </DataTemplate> 
    </sdk:DataGridTemplateColumn.CellEditingTemplate> 
    </sdk:DataGridTemplateColumn> 

EDIT 3

private void DatePicker_SelectedDateChanged(object sender, SelectionChangedEventArgs e) 
     { 
      (sender as DatePicker).GetBindingExpression(DatePicker.SelectedDateProperty).UpdateSource(); 
     } 

Byłem w stanie odświeżyć wiązanie zarówno przy użyciu kontroli zdarzenie selectedDatechange, a następnie odświeżenie wiązania nadawcy.

Nadal nie jestem pewien, dlaczego 2-way wiążące działanie nie będzie działać.

Czy ktoś może wyjaśnić, dlaczego tak się dzieje?

EDIT 4

wzór i właściwości

public DateTime? Start 
     { 
      get { return _Start; } 
      set 
      { 
       _Start = value; Dirty = true; 

       if (_Start.HasValue && _Due.HasValue && _Start.Value > _Due.Value) 
        _dataErrors["Start"] = "Start date cannot be greater than the Due date"; 
       else 
        if (_dataErrors.ContainsKey("Start")) 
         _dataErrors.Remove("Start"); 
       NotifyPropertyChanged(); NotifyPropertyChanged("CalcStatus"); 
      } 
     } 
     public DateTime? Due 
     { 
      get { return _Due; } 
      set 
      { 
       _Due = value; Dirty = true; 
       if (_Start.HasValue && _Due.HasValue && _Start.Value > _Due.Value) 
        _dataErrors["Start"] = "Start date cannot be greater than the Due date"; 
       else 
        if (_dataErrors.ContainsKey("Start")) 
         _dataErrors.Remove("Start"); 
       NotifyPropertyChanged("Due"); NotifyPropertyChanged("CalcStatus"); 
      } 
     } 
+0

Pokaż odpowiednie właściwości viewmodelu, do którego jest przypisany. Czy prawidłowo wdrażasz powiadomienie o zmianie właściwości? – Nkosi

+0

Tak, jestem, Model widoku Implementuje zdarzenie INotifyPropertyChanged i jeśli mam tylko jedną kontrolę w szablonie, to trafienie bez względu na to, która właściwość jest powiązana. W przypadku więcej niż jednej kontroli tylko ostatnia zostaje zaktualizowana.Dziwne jest to, że NotifyPropertyChanged jest wywoływana, gdy wybieram inną komórkę lub kolumnę, a następnie aktualizuje tylko ostatnią kontrolę, pozostałe właściwości są również trafione, ale przekazana wartość jest taka sama jak istniejąca wartość. –

+0

Dlaczego istnieje tag WPF, jeśli jest to Silverlight? :) BTW jest UpdateSourceTrigger PropertyChanged obsługiwane (lub przydatne)? –

Odpowiedz

2

Alright Chyba wreszcie naprawili go. Nadal nie jestem w 100% pewna, dlaczego to nie działało, ale utworzę nowy mały projekt i spróbuję znaleźć przyczynę.

To, co się stało, to zmodyfikowanie mojego NoitifyPropertyChangedEvent przez przekazanie go [CallerMemberName], aby nazwa właściwości wywołującej je była przekazywana automatycznie. Co oznacza, że ​​jeśli zmienię właściwość name na przykład "Start", nie muszę się martwić o aktualizację NotifyPropertyChanged("Start").

public event PropertyChangedEventHandler PropertyChanged; 

     public void NotifyPropertyChanged([CallerMemberName] string propertyName =null) 
     { 
      if (PropertyChanged != null) 
       PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 

To zadziałało dobrze dla wszystkich nieruchomości, z wyjątkiem sytuacji, gdy miałem DataTemplateColumn. Konwersja z powrotem do standardowego kodu i przekazanie właściwości propertyName wyraźnie rozwiązało mój problem.

public event PropertyChangedEventHandler PropertyChanged; 

     public void NotifyPropertyChanged(string propertyName) 
     { 
      if (PropertyChanged != null) 
       PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
Powiązane problemy