首页 > 解决方案 > ListView WPF 上的页脚

问题描述

我想ListView在他各自的列,许可证和扫描中添加一个页脚,其中两列的总和,我发现了类似的东西(这里)但是页脚没有显示,如果我在页脚中添加一个 4GridView列行显示但没有任何值。包含我也想应用于页脚的样式(我没有粘贴它以提供最小的功能示例
GridViewColumnHeader

这是预期的视图:
在此处输入图像描述

xml

<Window x:Class="WpfApp2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp2"
        xmlns:system="clr-namespace:System;assembly=mscorlib"
        xmlns:utils="Helper"
        mc:Ignorable="d"
        Title="MainWindow"
        Height="450"
        Width="800">
    <Window.DataContext>
        <local:ViewModel />
    </Window.DataContext>
    <Window.Resources>
        <CollectionViewSource x:Key="ViewSource"
                              Source="{Binding DataList}">
            <CollectionViewSource.GroupDescriptions>
                <PropertyGroupDescription PropertyName="ToOrder" />
            </CollectionViewSource.GroupDescriptions>
        </CollectionViewSource>
    </Window.Resources>

    <Grid>
        <ListView ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                  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:SumConverter x:Key="sumConverter" />
                                                </Grid.Resources>
                                                <Grid.RowDefinitions>
                                                    <RowDefinition/>
                                                    <RowDefinition/>
                                                </Grid.RowDefinitions>
                                                <Grid.ColumnDefinitions>
                                                    <ColumnDefinition Width="{Binding ElementName=Col1, Path=ActualWidth}"/>
                                                    <ColumnDefinition Width="{Binding ElementName=Col2, Path=ActualWidth}"/>
                                                    <ColumnDefinition Width="{Binding ElementName=Col3, Path=ActualWidth}"/>
                                                </Grid.ColumnDefinitions>
                                                <TextBlock Grid.Row="1"
                                                           Text="Sum: "
                                                           FontWeight="Bold" />
                                                <TextBlock Grid.Column="1"
                                                           Grid.Row="1"
                                                           Text="{Binding Path=Items, Converter={StaticResource sumConverter}, ConverterParameter=1}"/>
                                                <TextBlock Grid.Column="2"
                                                           Grid.Row="1"
                                                           Text="{Binding Path=Items, Converter={StaticResource sumConverter}, ConverterParameter=2}"/>
                                                <Line Grid.Column="0"
                                                      Grid.Row="0"
                                                      Grid.ColumnSpan="3"
                                                      Stroke="Black"
                                                      X2="500"
                                                      Fill="Black"
                                                      VerticalAlignment="Center" />
                                            </Grid>
                                            <ItemsPresenter />
                                        </DockPanel>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </GroupStyle.ContainerStyle>
                </GroupStyle>
            </ListView.GroupStyle>
            <ListView.View>
                <GridView x:Name="OverviewGridView">
                    <GridViewColumn DisplayMemberBinding="{Binding Date, StringFormat=dd.MM.yyyy}"
                                    Header="Date" 
                                    x:Name="Col1"/>
                    <GridViewColumn DisplayMemberBinding="{Binding LicenseCount}"
                                    Header="Licenses" 
                                    x:Name="Col2"/>
                    <GridViewColumn DisplayMemberBinding="{Binding ScansCount}"
                                    Header="Scans" 
                                    x:Name="Col3"/>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</Window>

视图模型

namespace WpfApp2
{
    using System;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Linq;
    using System.Runtime.CompilerServices;
    using WpfApp2.Annotations;

    public class OverView
    {
        public int ToGroup { get; set; } = 1;
        public DateTime Date { get; set; }
        public int LicenseCount { get; set; }
        public int ScansCount { get; set; }
    }

    public class ViewModel : INotifyPropertyChanged
    {
        private int _totalLicenses;
        private ObservableCollection<OverView> _dataList;
        private int _totalScans;

        public ViewModel()
        {
            OverView a = new OverView
                             {
                                 Date = DateTime.Now.Subtract(new TimeSpan(1, 0, 0, 0)),
                                 LicenseCount = 2,
                                 ScansCount = 7
                             };
            OverView b = new OverView
                             {
                                 Date = DateTime.Now.Subtract(new TimeSpan(5, 0, 0, 0)),
                                 LicenseCount = 3,
                                 ScansCount = 2
                             };
            OverView c = new OverView { Date = DateTime.Now, LicenseCount = 5, ScansCount = 4 };
            OverView d = new OverView
                             {
                                 Date = DateTime.Now.Subtract(new TimeSpan(7, 0, 0, 0)),
                                 LicenseCount = 1,
                                 ScansCount = 3
                             };

            DataList = new ObservableCollection<OverView> { a, b, c, d };

            TotalLicenses = DataList.Sum(overview => overview.LicenseCount);
            TotalScans = DataList.Sum(overview => overview.ScansCount);
        }

        public event PropertyChangedEventHandler PropertyChanged;
        public ObservableCollection<OverView> DataList
        {
            get => _dataList;
            set
            {
                _dataList = value;
                OnPropertyChanged();
            }
        }
        public int TotalLicenses
        {
            get => _totalLicenses;
            set
            {
                _totalLicenses = value;
                OnPropertyChanged();
            }
        }
        public int TotalScans
        {
            get => _totalScans;
            set
            {
                _totalScans = value;
                OnPropertyChanged();
            }
        }
        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) =>
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

和转换器

namespace WpfApp2
{
    #region Using

    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Windows.Data;

    #endregion

    public class SumConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            int sum = 0;
            if (value is IEnumerable<object> total)
            {
                foreach (object o in total)
                {
                    if (o is OverView overview)
                    {
                        int col = int.Parse((string)parameter);

                        sum += col == 1 ? overview.LicenseCount : overview.ScansCount;
                    }
                }

                return sum;
            }

            return 0;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => 1;
    }
}

提前致谢!

编辑,经过进一步测试,我成功地在 Overview 对象中创建了一个新属性以对其进行分组,然后使用转换器对我需要的列求和。结果如下:代码随解决方案更新。 在此处输入图像描述

标签: c#wpfxamlmvvm

解决方案


您不能将其集成到列表视图中,但您可以将其放在下面,如下所示:

            <StackPanel>
                <GridViewRowPresenter DockPanel.Dock="Bottom"
                              Content="Sum"
                              Columns="{Binding ElementName=OverviewGridView, Path=Columns}">
                </GridViewRowPresenter>
                <ListView
                  HorizontalAlignment="Stretch"
                  ItemsSource="{Binding DataList}">
                    <ListView.View>
                        <GridView x:Name="OverviewGridView">
                            <GridViewColumn DisplayMemberBinding="{Binding Date}" Header="Date"/>
                            <GridViewColumn DisplayMemberBinding="{Binding LicenseCount}" Header="Licenses"/>
                            <GridViewColumn DisplayMemberBinding="{Binding ScansCount}" Header="Scans"/>
                        </GridView>
                    </ListView.View>
                </ListView>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="{Binding ElementName=OverviewGridView, Path=Columns[0].ActualWidth}"/>
                        <ColumnDefinition Width="{Binding ElementName=OverviewGridView, Path=Columns[1].ActualWidth}"/>
                        <ColumnDefinition Width="{Binding ElementName=OverviewGridView, Path=Columns[2].ActualWidth}"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="Summe" Grid.Column="0" Margin="10,0"/>
                    <TextBlock Text="{Binding DataList, FallbackValue=0,Converter={StaticResource Summierer}, ConverterParameter=1}"  Margin="10,0" Grid.Column="1"/>
                    <TextBlock Text="{Binding DataList, FallbackValue=0,Converter={StaticResource Summierer}, ConverterParameter=2}"  Margin="10,0" Grid.Column="2"/>
                </Grid>
            </StackPanel>

在此处输入图像描述

这是我的转换器(需要重写!!我没有付出任何努力)

 public class SummUp: IValueConverter
{
    #region Convert
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var rtn = 0;
        var coll = (value as ObservableCollection<OverView>);
        var param = System.Convert.ToInt32(parameter);
        foreach (var item in coll)
        {
            if (param == 1)
            {
                rtn += item.LicenseCount;
            }
            else if (param == 2)
            {
                rtn += item.ScansCount;
            }
        }

        return rtn;
    }//END Convert
    #endregion Convert

    #region ConvertBack
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }//END ConvertBack 
    #endregion ConvertBack 

}//END class boolToNotVisibilityConverter : IValueConverter 

推荐阅读