GroupFooter en ListView - Blog de Oskar Alvarez

GroupFooter en ListView

En una de las preguntas de los foros, se comentaba a ver si era posible en una listview hacer un footer para indicar totales en una ListView, la verdad que no es muy complicado de realizar aprovechándonos de la propiedad ContainerStyle para GroupStyle, a continuación voy a poner el código de ejemplo.

El XAML de la ventana seria

 

  1. <Window x:Class="WpfApplication5.Window1"
  2.    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.    xmlns:local="clr-namespace:WpfApplication5"
  5.    Title="Window1" Width="640" Height="480">
  6.     <Window.Resources>
  7.         <local:MyDataSource x:Key="MyData" />
  8.         <CollectionViewSource x:Key="ViewSource" Source="{Binding Source={StaticResource MyData}, Path=Users}">
  9.             <CollectionViewSource.GroupDescriptions>
  10.                 <PropertyGroupDescription PropertyName="Country" />
  11.             </CollectionViewSource.GroupDescriptions>
  12.         </CollectionViewSource>
  13.     </Window.Resources>
  14.     <Grid x:Name="LayoutRoot">
  15.         <ListView ItemsSource="{Binding Source={StaticResource ViewSource}}">
  16.             <ListView.GroupStyle>
  17.                 <GroupStyle>
  18.                     <GroupStyle.ContainerStyle>
  19.                         <Style TargetType="{x:Type GroupItem}">
  20.                             <Setter Property="Template">
  21.                                 <Setter.Value>
  22.                                     <ControlTemplate TargetType="{x:Type GroupItem}">
  23.                                         <DockPanel>
  24.                                             <Grid DockPanel.Dock="Bottom">
  25.                                                 <Grid.Resources>
  26.                                                     <local:TotalSumConverter x:Key="sumConverter" />
  27.                                                 </Grid.Resources>
  28.                                                 <Grid.ColumnDefinitions>
  29.                                                     <ColumnDefinition Width="*" />
  30.                                                     <ColumnDefinition Width="*" />
  31.                                                 </Grid.ColumnDefinitions>
  32.                                                 <Grid.RowDefinitions>
  33.                                                     <RowDefinition />
  34.                                                     <RowDefinition />
  35.                                                 </Grid.RowDefinitions>
  36.                                                 <StackPanel Orientation="Horizontal">
  37.                                                     <TextBlock Grid.Column="0" Text="Total: " FontWeight="Bold"/>
  38.                                                     <TextBlock Grid.Column="0" Text="{Binding Path=Name}" />
  39.                                                 </StackPanel>
  40.                                                 <Line Grid.Column="1" Stroke="Black" X2="500" Fill="Black" VerticalAlignment="Center" />
  41.                                                 <TextBlock Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" Text="{Binding Path=Items, Converter={StaticResource sumConverter}}" />
  42.                                             </Grid>
  43.                                             <ItemsPresenter />
  44.                                         </DockPanel>
  45.                                     </ControlTemplate>
  46.                                 </Setter.Value>
  47.                             </Setter>
  48.                         </Style>
  49.                     </GroupStyle.ContainerStyle>
  50.                 </GroupStyle>
  51.             </ListView.GroupStyle>
  52.             <ListView.View>
  53.                 <GridView>
  54.                     <GridViewColumn Width="140" Header="Nombre" DisplayMemberBinding="{Binding Name}"/>
  55.                     <GridViewColumn Width="140" Header="Telefono" DisplayMemberBinding="{Binding Phone}"/>
  56.                     <GridViewColumn Width="140" Header="Ciudad" DisplayMemberBinding="{Binding Country}" />
  57.                     <GridViewColumn Width="140" Header="Total" DisplayMemberBinding="{Binding Total}" />
  58.                 </GridView>
  59.             </ListView.View>
  60.         </ListView>
  61.     </Grid>
  62. </Window>

 

Si os fijais hemos definido el estilo para GroupStyle y hemos indicado porque propiedad se agrupa en CollectionViewSource, luego hemos definido como queríamos representar ese pie, en este caso vamos a mostrar la suma de todos los items de ese grupo

Ahora vamos a seguir poniendo el código de las restantes clases necesarias

MyDataSource.cs

 

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.Linq;
  5. using System.Text;
  6. namespace WpfApplication5
  7. {
  8.     public class MyDataSource
  9.     {
  10.         public ObservableCollection<User>
  11.             Users { get; set; }
  12.         public MyDataSource()
  13.         {
  14.             Users = new ObservableCollection<User>();
  15.             LoadDummyData();
  16.         }
  17.         private void LoadDummyData()
  18.         {
  19.             Users.Add(new User() { Name = "Oscar", Phone = "(122) 555-1234", Country = "España", Total = 432 });
  20.             Users.Add(new User() { Name = "Maite", Phone = "(212) 555-1234", Country = "España", Total = 456 });
  21.             Users.Add(new User() { Name = "Javi", Phone = "(301) 555-1234", Country = "España", Total = 123 });
  22.             Users.Add(new User() { Name = "Joseba", Phone = "+33 (122) 555-1234", Country = "USA", Total = 333 });
  23.             Users.Add(new User() { Name = "Mike", Phone = "+33 (122) 555-1234", Country = "USA", Total = 222 });
  24.             Users.Add(new User() { Name = "Jim", Phone = "+33 (122) 555-1234", Country = "USA", Total = 444 });
  25.         }
  26.     }
  27. }

User.cs

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. namespace WpfApplication5
  6. {
  7.     public class User
  8.     {
  9.         public string Name { get; set; }
  10.         public string Phone { get; set; }
  11.         public string Country { get; set; }
  12.         public double Total { get; set; }
  13.     }
  14. }

TotalSumConverter.cs

 

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Windows.Data;
  7. namespace WpfApplication5
  8. {
  9.     public class TotalSumConverter : IValueConverter
  10.     {
  11.         public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  12.         {
  13.             var users = value as IEnumerable<object>;
  14.             if (users == null)
  15.                 return "€0.00"; double sum = 0;
  16.             foreach (var u in users)
  17.             {
  18.                 sum += ((User)u).Total;
  19.             } return sum.ToString("c");
  20.         }
  21.         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  22.         { throw new System.NotImplementedException(); }
  23.     }
  24. }

 

El resultado final seria

 

image

Fácil no?, espero que os sirva

Published 22/11/2009 9:17 por Oskar Alvarez
Archivado en:
Comparte este post:
http://geeks.ms/blogs/oalvarez/archive/2009/11/22/groupfooter-en-listview.aspx

Comentarios

# GroupFooter en ListView

En una de las preguntas de los foros, se comentaba a ver si era posible en una listview hacer un footer

Sunday, November 22, 2009 9:50 AM por .NET con oskar

# re: GroupFooter en ListView

Hola Oskar,

en primer lugar agradecerte el artículo, la duda es si se puede aplicar en WinForms.

Muchas gracias.

Monday, November 23, 2009 9:29 AM por ATP