Search code examples
wpfdatagridwpfdatagriddatetimepicker

Unexpected Behaviour with WPF Datagrid Grouping with DateTimePicker control


Inside my window, I have a simple datagrid control with a dateTimePicker column, and a textbox column. I group the rows inside the datagrid by a month-year string derived from the dateTimePicker. Here is the xaml for the columns and the grouping.....

                <DataGridTemplateColumn Header="Date" Width="100">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <xctk:DateTimePicker IsEnabled="True" Format="Custom" FormatString="M/d/yyyy h:mm" Value="{Binding theDate, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTemplateColumn Header="Text" Width="150">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBox TextWrapping="Wrap" AcceptsReturn="True" MaxLines="2" VerticalScrollBarVisibility="Auto" MaxLength="150" Text="{Binding theText, UpdateSourceTrigger=LostFocus, Mode=TwoWay}"></TextBox>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGrid.GroupStyle>
            <GroupStyle>
                <GroupStyle.HeaderTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <TextBlock Text="{Binding Name}" FontWeight="Bold" Padding="3"/>
                        </StackPanel>
                    </DataTemplate>
                </GroupStyle.HeaderTemplate>
            </GroupStyle>
        </DataGrid.GroupStyle>

I have a very simple class with the text string, and datetimepicker datetime, and a string for month-year that I create dynamically. Here is the C# code for the class...

public DateTime dueDate { get; set; }
public String task { get; set; }

private String _monthYear;
public String monthYear
{
    get { return dueDate.Month.ToString() + " - " + dueDate.Year.ToString(); }
}

Here is my initialization of the grouping

myCollectionView = CollectionViewSource.GetDefaultView(myObservableCollectionList);
myCollectionView.GroupDescriptions.Add(new PropertyGroupDescription("monthYear"));

MyDataGrid.ItemsSource = myCollectionView;
// In this case, myObservableCollectionList is an observable collection that holds the datagrid 
// rows. myCollectionView is an ICollectionView object

Everything is working properly except one very annoying piece of unexpected behavior. I don't know if this is a bug with the DateTimePicker control from the extended WPF toolkit.

Whenever I change the month or year on the DateTimePicker control and click on a new row or a different column in the same row, the row where I changed the date will not be grouped but will remain inside the old month-year date group until I sort it. This behavior would be fine if it was consistent HOWEVER...

If i were to change the month or year on the DateTimePicker control, and then tab through or click through the same DateTimePicker control (Not changing anything), and then click on a new row, the old row will be grouped into a new month - year category.

I'm not sure but I feel like this is a bug with the DateTimePicker control where it's calling some sort of event when you tab through the control even if you don't change date. However right now I'm pretty confused, and was wondering if anyone has any insight as to why this is happening.

*NOTE** I have tested this with and without the INotifyPropertyChanged, I do have the interface implemented, and the behavior occurs with and without it implemented I thought I would just leave it out for simplicity sake.

Any help is appreciated thank you!


Solution

  • I have fixed this issue, it was caused by the uses of both a _monthYear as well as a monthYear, so I guess whenever i would change the date, there would be multiple calls to change _monthYear. For whatever reason, I'm assuming something to do with the group description...

    taskScheduleCollection.GroupDescriptions.Add(new PropertyGroupDescription("monthYear"));
    

    maybe mixed in with the ValueChanged or a similar event inside the DateTimePicker would cause the grouping to re apply and new row groups would be created(I'm not 100% sure about this).

    I fixed this issue by just removing the _monthYear property as it was unnecessary and just keeping a single monthYear property that was dependent on the date.

        public String monthYear
        {
            get { return _date.Month.ToString() + " - " + _date.Year.ToString(); }
        }
    

    The grouping now only reapplys whenever i sort my list collection, which is the consistent behavior that I want.