2

It seems that the DisplayDate doesn't bind correctly when the DatePicker is inside a ControlTemplate.

This is how I bind the DisplayDate to the DatePicker through MVVM. But the DatePicker wont display the CustomDisplayDate correctly. It keep show the default display date which is DateTime.Now().

Keep in mind that this code does work if the DatePicker is not inside a ControlTemplate.

Any suggestions on how to solve this?

XAML code:

<Window.Resources>
    <ControlTemplate x:Key="DateField">
        <StackPanel>
            <TextBlock Text="Custom Display Date:" />
            <TextBlock Text="{Binding CustomDisplayDate}"/>
            <DatePicker 
                SelectedDate="{Binding CustomSelectedDate}" 
                DisplayDate="{Binding CustomDisplayDate}" 
                HorizontalAlignment="Left" 
                VerticalAlignment="Top"/>
        </StackPanel>
    </ControlTemplate>
</Window.Resources>
<Grid>
    <ContentControl Template="{StaticResource DateField}" />
</Grid>

and the ViewModel:

public class MainWindowViewModel
{
  public MainWindowViewModel()
  {
     CustomDisplayDate = DateTime.Now.AddDays(5);
  }

  public DateTime? CustomSelectedDate { get; set; }
  public DateTime CustomDisplayDate { get; set; }
}
H.B.
  • 166,899
  • 29
  • 327
  • 400
Danny Pham
  • 31
  • 1
  • 3

2 Answers2

1

I realize that this is pretty old but I just stumbled in to this same issue today. I'm not certain why this happens and I'm fairly certain I had my bindings established correctly.

I did find a work around, at least in my case. I wired up the PreparingCellForEdit event to my ViewModel. That method peeked examines the column to determine if the editing cell belongs to the correct column of datepickers and I also examined if the date it is bound to is null which told me that it was a new row. I can then grab the datepicker and set its DisplayDate from code.

private void OnPreparingCellForEdit(DataGridPreparingCellForEditEventArgs e)
{
    DataGridColumn sourceColumn = e.Column;
    DataGridRow sourceRow = e.Row;
    ScheduleDate data = (ScheduleDate) sourceRow.DataContext;

    if (string.Equals(sourceColumn.Header.ToString(), "Work Date") && !data.WorkDate.HasValue)
    {
        var dp = e.EditingElement.GetVisualChild<DatePicker>() as DatePicker;
        dp.DisplayDate = this.WorkDate;
    }
}
Chandler
  • 11
  • 1
1

The first issue here is that you're not using INotifyPropertyChanged.

Please look into articles linked below:

Community
  • 1
  • 1
Anatolii Gabuza
  • 6,184
  • 2
  • 36
  • 54
  • In the simple sample code i posted, the CustomDisplayDate is set in the constructor, so there is no need for INotifyPropertyChanged. The property doesn't changed after the first load. Please note that this code does work if I create the DatePicker outside the ControlTemplate. – Danny Pham Dec 06 '11 at 11:40
  • @DannyPham Yep. You are right, in your code sample it will not change View. Without `INotifyPropertyChanged` it just cannot know when were made any changes to ViewModel property. – Anatolii Gabuza Dec 06 '11 at 12:21
  • Dear anatoliiG, thanks for your suggestion about INotifyPropertyhanged. But in this sample this is not an issue. If you try the sample code, you will see the , just above the DatePicker, display the CustomDisplayDate just fine. So the View does know about the +5 days. The problem here is when the DatePicker is inside the ControlTemplate, it won’t show the DisplayDate in the Calendar correctly. It seems like the DisplayDate binding got lost somewhere when accessing the DatePicker through a ContentControl. – Danny Pham Dec 06 '11 at 17:28
  • @DannyPham Try to add `Source` property for binding within template. – Anatolii Gabuza Dec 07 '11 at 09:48
  • I am not really sure what is Source property on the template... Could you please refer me to some code samples? – Danny Pham Dec 07 '11 at 14:32
  • @DannyPham Something like: `{Binding CustomSelectedDate, Source={StaticResource MainWindowViewModel}}`. – Anatolii Gabuza Dec 07 '11 at 16:44