Only the last control in the Data Template column is updated.

I have a DataTemplate column with 2 DatePickers that is associated with two properties. When the data in this control changes, only the last control is updated.

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

In this case, if I update both Start and Due Only, it will be updated. Also, binding works fine, because if I put breakPoint in Start in my Model class, it gets hit, but the passed value is the original Start value

EDIT 1

After some debugging, I found out that if I have only one control inside my DataTemplate , it works fine. Also, when I change the date, the break point immediately hits. But if I have more than one control, the breakpoint doesn't hit until I focus on the column and then only the last binding will work.

EDIT 2

After some debugging with mroe, I noticed that it will work fine if I use only CellTemplate and drop the EditTemplate cell

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

I was able to update the binding for both controls using the selectedDatechange event, and then update the binding to the sender.

I'm still not sure why working with two binding methods will not work.

Can someone explain why this is happening?

EDIT 4

Model and properties

  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"); } } 
+6
source share
1 answer

Ok, I think I finally fixed it. I'm still not 100% sure why it did not work, but I will create a new small project and try to find out the reason.

It so happened that I changed my NoitifyPropertyChangedEvent by passing it [CallerMemberName] so that the name of the property that called it is passed automatically. This means that if I change the name property, such as "Start", I don’t have to worry about updating NotifyPropertyChanged("Start") .

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

This worked fine for all properties except when I had a DataTemplateColumn . By converting it back to standard code and passing the property Name, I explicitly fixed my problem.

 public event PropertyChangedEventHandler PropertyChanged; public void NotifyPropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } 
+2
source

All Articles