c# - 用日期分组列表框

标签 c# wpf mvvm

我不知道如何实现这一点,但我在 ListBox 中有一个日期和时间列。如果日期已经存在,则不应显示日期列。我知道结合 ListCollectionView 和 Listview/DataGrids,这很可能是可能的。但是我可以用一个 ListBox 和一个 List 来实现吗?请记住,我使用的是 MVVM 原则。这是我的列表框:

<ListBox Grid.Row="2" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ItemsSource="{Binding Schedules}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Background="Transparent">
                            <Grid Background="Transparent">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition  Width="100"/>
                                    <ColumnDefinition  Width="100"/>
                                    <ColumnDefinition/>
                                </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition/>
                                </Grid.RowDefinitions>
                                <TextBlock Grid.Column="0" Grid.Row="0"  Text="{Binding MyDateTime, StringFormat='d' }" HorizontalAlignment="Left"  VerticalAlignment="Center"/>
                                <TextBlock Grid.Column="1" Grid.Row="0"  Text="{Binding MyDateTime, StringFormat='t'}" HorizontalAlignment="Left"  VerticalAlignment="Center"/>
                                <TextBlock Grid.Column="2" Grid.Row="0"  Text="{Binding SomeText}"  TextTrimming="WordEllipsis" LineStackingStrategy="MaxHeight" MaxHeight="20" HorizontalAlignment="Left"  VerticalAlignment="Center"/>
                            </Grid>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

我在 excel 中做了这个来举例说明我想要实现的目标: enter image description here

我想要用黄色突出显示的效果

最佳答案

DateTimeText 转换器

// Order Schedules using System.Linq
public class ToOrderedListConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        List<ScheduleItem> schedules = (List<ScheduleItem>)value;
        var subset = from item in schedules
                     orderby item.MyDateTime.TimeOfDay
                     orderby item.MyDateTime.ToString("yyyy/MM/dd") descending
                     select item;
        return subset.ToList();
    }

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

// Show only first occurrence of date
public class DateToVisibilityConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        DateTime currentItem = (DateTime)values[0];
        List<ScheduleItem> schedules = (List<ScheduleItem>)values[1];
        ScheduleItem firstOccurrence =
            schedules.Find(item => item.MyDateTime.Year == currentItem.Year
                                && item.MyDateTime.Month == currentItem.Month
                                && item.MyDateTime.Day == currentItem.Day);

        if (firstOccurrence.MyDateTime == currentItem)
            return Visibility.Visible;
        else return Visibility.Collapsed;
    }

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

XAML

<ListBox Grid.Row="2" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
         ItemsSource="{Binding Schedules, Converter={StaticResource ToOrderedListConverter}}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Background="Transparent">
                <Grid Background="Transparent">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="100"/>
                        <ColumnDefinition Width="100"/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <TextBlock Grid.Column="0" Grid.Row="0" Text="{Binding MyDateTime, StringFormat='dd/MM/yyyy'}" HorizontalAlignment="Left" VerticalAlignment="Center">
                        <TextBlock.Visibility>
                            <MultiBinding Converter="{StaticResource DateToVisibilityConverter}">
                                <Binding Path="MyDateTime"/>
                                <Binding RelativeSource="{RelativeSource AncestorType={x:Type ListBox}}" 
                                         Path="ItemsSource"/>
                            </MultiBinding>
                        </TextBlock.Visibility>
                    </TextBlock>
                    <TextBlock Grid.Column="1" Grid.Row="0" Text="{Binding MyDateTime, StringFormat='t'}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
                    <TextBlock Grid.Column="2" Grid.Row="0" Text="{Binding SomeText}"  TextTrimming="WordEllipsis" LineStackingStrategy="MaxHeight" MaxHeight="20" HorizontalAlignment="Left" VerticalAlignment="Center"/>
                </Grid>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

关于c# - 用日期分组列表框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41062833/

相关文章:

C# 和 MySql 过程

c# - 有什么方法可以阻止光线转换穿过物体吗?

c# - 使用内联对象初始化器与将变量 1 传递给 EF Select 之间的细微差别

c# - 当用户移动窗口时 PushFrame 锁定 WPF 窗口

wpf - WPF是否支持本地读取/写入WMF/EMF文件?

android - 为什么我的 Activity 没有看到观察到的物体变化?

c# - 在 Winrt 和 MVVM 模式中显示来自 Uri 的图像

c# - 计算 .NET Core 项目的代码指标?

c# - 在 MVVM 中显示对话框并设置对话框选项

java - SQLite MVVM返回并获取Activity中的rowId