Datagrid分组-行总计

时间:2018-11-08 12:45:16

标签: c# wpf xaml

我正在尝试使用行总计实现WPF DataGrid分组。

我从该论坛中找到了随附的解决方案,该解决方案被标记为“有效” 。不幸的是,它仅在只有一行的情况下才起作用,例如行1、3和4。在只有一行的地方(例如第2行和第3行)则不起作用。如果尝试更改第1行的长度,则平均值也改变。但是当我更改第2行和第3行时,平均值不会改变。

为什么它只能处理一行但不能处理多行?

这里是XAML:

<Window x:Class="WpfApplication4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        xmlns:local="clr-namespace:WpfApplication4"
        >

    <Window.Resources>
        <local:WeightAvgConverter x:Key="WeightAvgConverter"/>
        <local:GroupItemStyleSelector x:Key="GroupItemStyleSelector"/>
        <Style x:Key="GroupHeaderStyleForFirstLevel" TargetType="{x:Type GroupItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type GroupItem}">
                        <ItemsPresenter />
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <Style x:Key="GroupHeaderStyleForSecondLevel" TargetType="{x:Type GroupItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type GroupItem}">
                        <Expander IsExpanded="True">
                            <Expander.Header>
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock><Bold>Width: </Bold></TextBlock>
                                    <TextBlock Text="{Binding Items[0].Width }" Width="50"/>
                                    <TextBlock><Bold>Length: </Bold></TextBlock>
                                    <TextBlock Text="{Binding Items[0].Length }" Width="50"/>
                                    <TextBlock><Bold>Avarage Amount: </Bold></TextBlock>
                                    <TextBlock Text="{Binding Converter={StaticResource WeightAvgConverter}}" />
                                </StackPanel>
                            </Expander.Header>
                            <ItemsPresenter />
                        </Expander>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>

    <Grid>
        <DataGrid AutoGenerateColumns="True" ItemsSource="{Binding}" Margin="11,20,8,9" Name="dataGrid1" 
                     VirtualizingStackPanel.VirtualizationMode="Recycling">
            <DataGrid.GroupStyle>
                <GroupStyle ContainerStyleSelector="{StaticResource GroupItemStyleSelector}" />
            </DataGrid.GroupStyle>
        </DataGrid>
    </Grid>
</Window>

后面的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;


namespace WpfApplication4
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Loaded += new RoutedEventHandler(Window4_Loaded);
        }
        void Window4_Loaded(object sender, RoutedEventArgs e)
        {

            ObservableCollection<Repository> Repositories = new ObservableCollection<Repository>();
            Repositories.Add(new Repository(1200, 2000, 300.6f));
            Repositories.Add(new Repository(1200, 3000, 123.36f));
            Repositories.Add(new Repository(1200, 3000, 33.3f));
            Repositories.Add(new Repository(1000, 1000, 123.36f));
            Repositories.Add(new Repository(1000, 1000, 77.8f));
            Repositories.Add(new Repository(1000, 1500, 183.0066f));
            Repositories.Add(new Repository(1000, 1600, 544.6f));


            CollectionViewSource view = new CollectionViewSource();
            view.Source = Repositories;
            view.GroupDescriptions.Add(new PropertyGroupDescription("Width"));
            view.GroupDescriptions.Add(new PropertyGroupDescription("Length"));

            dataGrid1.DataContext = view;
        }
    }



    public class WeightAvgConverter : IValueConverter
    {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            CollectionViewGroup group = value as CollectionViewGroup;

            float sum = 0;

            for (int j = 0; j < group.ItemCount; j++)
            {
                Repository r = (Repository)group.Items[j];
                sum += r.Weight;
            }
            return (float)(sum / group.ItemCount);
        }

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

        #endregion
    }

    public class GroupItemStyleSelector : StyleSelector
    {
        public override Style SelectStyle(object item, DependencyObject container)
        {
            Style s;

            CollectionViewGroup group = item as CollectionViewGroup;
            Window window = Application.Current.MainWindow;
            if (!group.IsBottomLevel)
            {
                s = window.FindResource("GroupHeaderStyleForFirstLevel") as Style;
            }
            else
            {
                s = window.FindResource("GroupHeaderStyleForSecondLevel") as Style;
            }

            return s;
        }
    }

    public class Repository
    {
        private int _width;
        private int _length;
        private float _weight;

        public Repository(int width, int length, float weight)
        {
            _width = width;
            _length = length;
            _weight = weight;
        }

        public int Width
        {
            get { return _width; }
            set { _width = value; }
        }
        public int Length
        {
            get { return _length; }
            set { _length = value; }
        }
        public float Weight
        {
            get { return _weight; }
            set { _weight = value; }
        }
    }
}

0 个答案:

没有答案