您应该首先确定与上一个条目相比具有新一周的条目。一种方法是编写一个比较器,将先前条目的日期与当前条目的日期进行比较:
public class WeekComparer : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values.Length != 2)
{
throw new Exception("Bad values");
}
var prev = values[0] as DateTime?;
// first entry has no predecessor, so the predecessor is not a different week
if (!prev.HasValue)
{
return true;
}
var dt1 = prev.Value;
var dt2 = (DateTime)values[1];
if (Math.Abs((dt1 - dt2).Days) > 7)
{
return false;
}
// assume monday to be the first day of week
var dow1 = (dt1.DayOfWeek + 7 - DayOfWeek.Monday) % 7;
var dow2 = (dt2.DayOfWeek + 7 - DayOfWeek.Monday) % 7;
var result = (dow1 < dow2) == (dt1 < dt2);
return result;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
请注意,此比较器可能不完整。在计算 Timespan.Days 进行比较之前,可能需要删除 Time 部分。
然后您可以在WeekComparer 的结果上使用ListViewItem.Style 和Trigger。使用RelativeSource PreviousData获取上一个item值与当前item进行比较:
<Grid x:Name="grid1">
<Grid.Resources>
<local:WeekComparer x:Key="sameWeekComparer"/>
</Grid.Resources>
<ListView x:Name="lv1" ItemsSource="{Binding}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Style.Triggers>
<DataTrigger Value="False">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource sameWeekComparer}">
<Binding Path="MyDate" RelativeSource="{RelativeSource PreviousData}"/>
<Binding Path="MyDate"/>
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="BorderThickness" Value="0 4 0 0"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView x:Name="gv1">
<GridViewColumn DisplayMemberBinding="{Binding Name}" Header="Name"/>
<GridViewColumn DisplayMemberBinding="{Binding MyDate}" Header="MyDate"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
这将使用Red BorderBrush 和仅在项目上方绘制边框的BorderThickness 绘制日期与前几行日期不同的行。您可以在Trigger 中应用任何其他类型的样式更改。
将 Grid 视为某个窗口的内容。我用以下数据进行了测试:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
List<MyDateVM> items = new List<MyDateVM>();
items.Add(new MyDateVM { Name = "Test 1", MyDate = new DateTime(2018, 12, 31) }); // first entry
items.Add(new MyDateVM { Name = "Test 2", MyDate = new DateTime(2019, 1, 6) }); // same week as end of december 2018
items.Add(new MyDateVM { Name = "Test 3", MyDate = new DateTime(2019, 1, 3) }); // changed order of date
items.Add(new MyDateVM { Name = "Test 4", MyDate = new DateTime(2019, 1, 9) }); // new week
items.Add(new MyDateVM { Name = "Test 5", MyDate = new DateTime(2019, 2, 10) }); // long gap, new week
grid1.DataContext = items;
}
}
MyDateVM 只是一个用于存储项目属性的普通数据类。