ItemsControl 中的 GroupStyle HeaderTemplate 未正确更新

GroupStyle HeaderTemplate in an ItemsControl does not update correctly

我正在为消息收件箱设计布局,目前正在根据 days/weeks/months/years 自动分隔消息。更具体地说,我有一个 header 表示 "Today" 表示在当前日期收到的所有消息,"Yesterday" 表示昨天,“3+ 天前”表示 3 到 6 天前的任何消息。 "Last week" 7-13 天前的任何事,举几个例子。你明白了。

到目前为止,除了一件事,所有这一切都很好。如果我在一夜之间离开应用程序,我今天的消息将被标记为 "Today",但所有旧的 header 都不会改变。所以昨天也被标记为 "Today",2 天前是 "Yesterday" 等等。它们仍然按应有的方式分组,只是标题不会更新。感觉它缺少某种 OnPropertyChanged 功能,但它在当前状态下如何工作?

我的 GroupStyle 是如何设置的:

<ItemsControl>
  <ItemsControl.Resources>
    <CollectionViewSource x:Key="MessageList" Source="{Binding Messages}">
      <CollectionViewSource.GroupDescriptions>
        <PropertyGroupDescription PropertyName="MessageDate" />
      </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>
  </ItemsControl.Resources>
  <ItemsControl.ItemsSource>
    <Binding Source="{StaticResource MessageList}"/>
  </ItemsControl.ItemsSource>
  <ItemsControl.GroupStyle>
   <GroupStyle>
     <GroupStyle.HeaderTemplate>
       <DataTemplate>
         <StackPanel Margin="0 0 0 15">
           <TextBlock Text="{Binding Path=Items[0].MessageDate, Converter={StaticResource DateTimeToStringConverter}}"/>
           <Path Data="m 0 0 100 0"/>
          </StackPanel>
        </DataTemplate>
      </GroupStyle.HeaderTemplate>
    </GroupStyle>
  </ItemsControl.GroupStyle>
</ItemsControl>

我的转换器(将 DateTime 更改为要显示的字符串)

public class DateTimeToStringConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if ((DateTime)value == DateTime.Now.Date)
        {
            return "Today";
        }
        else if ((DateTime)value == DateTime.Now.AddDays(-1).Date)
        {
            return "Yesterday";
        }
        else if ((DateTime)value == DateTime.Now.AddDays(-2).Date)
        {
            return "2 Days Ago";
        }
        return "3+ Days Ago";
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }

还可以补充一点,如果我重新启动应用程序,它仍然可以工作,但我不能让它过夜而不发生故障,这太烦人了,无法忽视。

如果您希望它起作用,您需要在每天午夜之前为数据绑定 MessageDate 属性 引发 PropertyChanged 事件。在引发此事件之前不会再次调用转换器。

您可以使用 Quartz.NET or FluentScheduler 等任务调度框架来 运行 在特定时间在您的视图模型中引发事件的代码。