Как создать нижний колонтитул группы в WPF ListView (GridView) - PullRequest
26 голосов
/ 24 марта 2009

У меня есть ListView, который отображает заказы на продажу и группирует их по статусу. В WinForms внизу каждой группы был нижний колонтитул, в котором отображалась общая цена продажи для каждой группы, и я хотел бы сделать то же самое в WPF.

Я понял, как группировать заказы, но не могу понять, как создать нижний колонтитул.

Это мой текущий стиль группы:

<ListView.GroupStyle>
            <GroupStyle HidesIfEmpty="True">
                <GroupStyle.HeaderTemplate>
                    <DataTemplate>
                        <!--CollectionViewGroup.Name will be assigned the value of Status for that group.-->
                        <!--/560197/kak-sgruppirovat-elementy-v-wpf-listview>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <TextBlock Grid.Column="0" Text="{Binding Path=Name}" HorizontalAlignment="Left" FontWeight="Bold"  Foreground="Black"/>
                            <Line Grid.Column="1" Stroke="Black" X2="500" Fill="Black" VerticalAlignment="Center" />
                        </Grid>
                    </DataTemplate>
                </GroupStyle.HeaderTemplate>
            </GroupStyle>
        </ListView.GroupStyle>

1 Ответ

65 голосов
/ 25 марта 2009

Если вы ищете что-то вроде этого:

WPF Grouping with Total Sums
(источник: bendewey.com )

Затем вы можете использовать свойство Template для ContainerStyle для GroupStyle. В этом примере я использую DockPanel, с сеткой, которую вы поставили, Docked внизу, а ItemsPresenter заполняет оставшуюся часть. Кроме того, для суммирования предметов вам нужно использовать конвертер, который находится внизу.

Window.xaml

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="WpfApplication1.Window3"
    x:Name="Window"
    Title="Window3"
    xmlns:local="clr-namespace:WpfApplication1"
    Width="640" Height="480">
    <Window.Resources>
        <local:MyDataSource x:Key="MyData" />
        <CollectionViewSource x:Key="ViewSource" Source="{Binding Source={StaticResource MyData}, Path=Users}">
            <CollectionViewSource.GroupDescriptions>
                <PropertyGroupDescription PropertyName="Country" />
            </CollectionViewSource.GroupDescriptions>
        </CollectionViewSource>
    </Window.Resources>
    <Grid x:Name="LayoutRoot">
      <ListView ItemsSource="{Binding Source={StaticResource ViewSource}}">
        <ListView.GroupStyle>
            <GroupStyle>
                <GroupStyle.ContainerStyle>
                    <Style TargetType="{x:Type GroupItem}">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type GroupItem}">
                                      <DockPanel>
                                        <Grid DockPanel.Dock="Bottom">
                                            <Grid.Resources>
                                                <local:TotalSumConverter x:Key="sumConverter" />
                                            </Grid.Resources>
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="*" />
                                                <ColumnDefinition Width="*" />
                                            </Grid.ColumnDefinitions>
                                            <Grid.RowDefinitions>
                                                <RowDefinition />
                                                <RowDefinition />
                                            </Grid.RowDefinitions>
                                            <StackPanel Orientation="Horizontal">
                                                <TextBlock Grid.Column="0" Text="Total: " FontWeight="Bold"/>
                                                <TextBlock Grid.Column="0" Text="{Binding Path=Name}" />
                                            </StackPanel>
                                            <Line Grid.Column="1" Stroke="Black" X2="500" Fill="Black" VerticalAlignment="Center" />

                                            <TextBlock Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" Text="{Binding Path=Items, Converter={StaticResource sumConverter}}" />
                                        </Grid>
                                    <ItemsPresenter />
                                </DockPanel>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </GroupStyle.ContainerStyle>
            </GroupStyle>
        </ListView.GroupStyle>
        <ListView.View>
           <GridView>
            <GridViewColumn Width="140" Header="Name" DisplayMemberBinding="{Binding Name}"/>
            <GridViewColumn Width="140" Header="Phone Number" DisplayMemberBinding="{Binding Phone}"/>
            <GridViewColumn Width="140" Header="Country" DisplayMemberBinding="{Binding Country}" />
            <GridViewColumn Width="140" Header="Total" DisplayMemberBinding="{Binding Total}" />
           </GridView>
          </ListView.View>
      </ListView>

    </Grid>
</Window>

MyDataSource.cs

public class MyDataSource
{
    public ObservableCollection<User> Users { get; set; }

    public MyDataSource()
    {
        Users = new ObservableCollection<User>();
        LoadDummyData();
    }

    private void LoadDummyData()
    {
        Users.Add(new User()
        {
            Name = "Frank",
            Phone = "(122) 555-1234",
            Country = "USA",
            Total = 432
        });

        Users.Add(new User()
        {
            Name = "Bob",
            Phone = "(212) 555-1234",
            Country = "USA",
            Total = 456
        });

        Users.Add(new User()
        {
            Name = "Mark",
            Phone = "(301) 555-1234",
            Country = "USA",
            Total = 123
        });

        Users.Add(new User()
        {
            Name = "Pierre",
            Phone = "+33 (122) 555-1234",
            Country = "France",
            Total = 333
        });

        Users.Add(new User()
        {
            Name = "Jacques",
            Phone = "+33 (122) 555-1234",
            Country = "France",
            Total = 222
        });

        Users.Add(new User()
        {
            Name = "Olivier",
            Phone = "+33 (122) 555-1234",
            Country = "France",
            Total = 444
        });
    }
}

User.cs

public class User
{
    public string Name { get; set; }
    public string Phone { get; set; }
    public string Country { get; set; }
    public double Total { get; set; }
}

TotalSumConverter.cs

public class TotalSumConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var users = value as IEnumerable<object>;
        if (users == null)
            return "$0.00";

        double sum = 0;

        foreach (var u in users)
        {
            sum += ((User)u).Total;
        }


        return sum.ToString("c");
    }

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