WPF DataGrid中自定义行分组

3

我想制作一个类似这个的DataGrid example

现在我做了一个看起来像这样的DataGrid

DataGrid

这是我的代码:

<DataGrid
    ScrollViewer.IsDeferredScrollingEnabled="True"
    Grid.Row="1"
    AutoGenerateColumns="False"
    CanUserAddRows="False"
    CanUserDeleteRows="False"
    CanUserSortColumns="True"
    EnableColumnVirtualization="True"
    EnableRowVirtualization="True"
    ItemsSource="{Binding MusicManager.MusicDataManager.Albums.Albums}"
    VirtualizingPanel.ScrollUnit="Pixel"
    VirtualizingStackPanel.VirtualizationMode="Recycling">
    <DataGrid.Columns>
        <DataGridTemplateColumn
            Width="auto"
            MaxWidth="150"
            Header="Duration">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*" />
                            <RowDefinition Height="auto" />
                            <RowDefinition Height="auto" />
                            <RowDefinition Height="auto" />
                            <RowDefinition Height="auto" />
                        </Grid.RowDefinitions>

                        <myControls:ImageProviderViewer
                            Grid.Row="0"
                            Width="90"
                            Height="90"
                            Margin="0"
                            HidePlaceholderAtBeginning="True"
                            HighPriorityImage="True">
                            <myControls:ImageProviderViewer.ImageProvider>
                                <MultiBinding Converter="{StaticResource AlbumCoverConverter}">
                                    <Binding Path="DataContext" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=UserControl}" />
                                    <Binding Path="Guid" />
                                </MultiBinding>
                            </myControls:ImageProviderViewer.ImageProvider>
                            <myControls:ImageProviderViewer.Placeholder>
                                <Viewbox Width="85" Height="85">
                                    <Path Fill="Gray" Data="{StaticResource VectorMicrophone}" />
                                </Viewbox>
                            </myControls:ImageProviderViewer.Placeholder>
                        </myControls:ImageProviderViewer>


                        <TextBlock
                            Grid.Row="1"
                            Grid.ColumnSpan="2"
                            Width="auto"
                            Margin="2"
                            FontSize="12"
                            Text="{Binding Name}"
                            TextWrapping="Wrap" />
                        <TextBlock
                            Grid.Row="2"
                            Grid.ColumnSpan="2"
                            Width="auto"
                            Margin="2"
                            FontSize="12"
                            Text="{Binding Artists, Converter={StaticResource AlbumArtistConverter}}"
                            TextWrapping="Wrap" />
                        <TextBlock
                            Grid.Row="3"
                            Grid.ColumnSpan="2"
                            Width="auto"
                            Margin="2"
                            FontSize="12"
                            TextWrapping="Wrap">
                            <TextBlock.Text>
                                <MultiBinding Converter="{StaticResource AlbumTracksConverter}" StringFormat="Tracks:   {0:F2}">
                                    <Binding Path="DataContext" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=UserControl}" />
                                    <Binding Path="Guid" />
                                </MultiBinding>
                            </TextBlock.Text>
                        </TextBlock>
                    </Grid>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>

        <DataGridTemplateColumn Width="*">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <DataGrid
                        AutoGenerateColumns="False"
                        CanUserAddRows="False"
                        CanUserDeleteRows="False"
                        CanUserSortColumns="True"
                        EnableColumnVirtualization="True"
                        EnableRowVirtualization="True">
                        <i:Interaction.Behaviors>
                            <services:IgnoreMouseWheelBehavior />
                        </i:Interaction.Behaviors>
                        <DataGrid.ItemsSource>
                            <MultiBinding Converter="{StaticResource AlbumTracksCollectionConverter}">
                                <Binding Path="DataContext" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=UserControl}" />
                                <Binding Path="Guid" />
                            </MultiBinding>
                        </DataGrid.ItemsSource>
                        <DataGrid.Columns>
                            <DataGridTemplateColumn
                                Width="*"
                                MaxWidth="500"
                                Header="Title">
                                <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <TextBlock Text="{Binding Title}" TextWrapping="Wrap" />
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>


                            <DataGridTemplateColumn
                                Width="*"
                                MaxWidth="500"
                                Header="Album">
                                <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <TextBlock Text="{Binding Album.Name}" TextWrapping="Wrap" />
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>

                            <DataGridTemplateColumn
                                Width="auto"
                                MaxWidth="500"
                                Header="Duration">
                                <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <TextBlock Text="{Binding Duration}" TextWrapping="Wrap" />
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>

                            <DataGridTemplateColumn
                                Width="auto"
                                MaxWidth="500"
                                Header="Year">
                                <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <TextBlock Text="{Binding Year}" TextWrapping="Wrap" />
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>
                        </DataGrid.Columns>
                    </DataGrid>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>

    </DataGrid.Columns>
</DataGrid>

但这不是我所需要的。 DataGrid在滚动时非常缓慢。 此外,我需要一次调整所有列的大小。
有没有解决这个问题的方法?
1个回答

2
您可以使用 DataGrid 的内置分组功能。我将展示一个带有所需布局的简化示例,但需要自定义 Expanders、DataGridColumnHeader、Images 等内容。
我的简化项类:
public class AlbumVm
{
    public string Name { get; set; }
    public Brush Color { get; set; }
}

public class SongVm
{
    public string Title { get; set; }
    public string Duration { get; set; }

    public AlbumVm Album { get; set; }
}

我将 Name="Music" 的 ItemsSource 分配给了 DataGrid(包含 125 张专辑,每张专辑有 5 首歌曲)。

var colors = new[] { Brushes.Crimson, Brushes.LimeGreen, Brushes.Cyan };
var albums = Enumerable.Range(1, 125)
             .Select(i => new AlbumVm {Name = "A" + i, Color = colors[i%colors.Length]});

var songs = albums.SelectMany(a => Enumerable.Range(1, 5)
                                   .Select(i => new SongVm {Title = a.Name + "." + i, Album = a, Duration = i + ":00"}))
                    .ToList();

var songsView = new ListCollectionView(songs);
songsView.GroupDescriptions.Add(new PropertyGroupDescription("Album.Name"));

Music.ItemsSource = songsView;

ListCollectionView支持分组功能。

以下是具有自定义GroupStyle的dataGrid(VirtualizingPanel.IsVirtualizingWhenGrouping属性需要.Net 4.5!)

<DataGrid Name="Music" 
            CanUserAddRows="False"
            CanUserDeleteRows="False"
            AutoGenerateColumns="False" 
            EnableColumnVirtualization="True"
            EnableRowVirtualization="True"
            VirtualizingStackPanel.IsVirtualizing="True"
            VirtualizingPanel.IsVirtualizingWhenGrouping="True"
            VirtualizingStackPanel.VirtualizationMode="Recycling"
            ColumnWidth="*">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Title" Binding="{Binding Path=Title}"/>
        <DataGridTextColumn Header="Album" Binding="{Binding Path=Album.Name}"/>
        <DataGridTextColumn Header="Duration" Binding="{Binding Path=Duration}"/>
    </DataGrid.Columns>

    <DataGrid.GroupStyle>
        <GroupStyle>
            <GroupStyle.ContainerStyle>
                <Style TargetType="{x:Type GroupItem}">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type GroupItem}">
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition/>
                                    </Grid.ColumnDefinitions>

                                    <!--Image placeholder-->
                                    <Border Margin="5" Width="100" 
                                            Background="{Binding Path=Items[0].Album.Color}"/>

                                    <Expander Grid.Column="1" IsExpanded="True">
                                        <Expander.Header>
                                            <StackPanel Orientation="Horizontal">
                                                <TextBlock Text="{Binding Path=Name}" Margin="5"/>
                                                <TextBlock Text="{Binding Path=ItemCount}" Margin="5"/>
                                            </StackPanel>
                                        </Expander.Header>
                                        <ItemsPresenter />
                                    </Expander>
                                </Grid>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </GroupStyle.ContainerStyle>
        </GroupStyle>
    </DataGrid.GroupStyle>
</DataGrid>

预览

相关帖子:

WPF DataGrid分组并计算总和及其他字段

WPF DataGrid分组虚拟化


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接