Reputation: 11
Hello i'm weary beginning in coding and this is my first serious application. I have data grid with grouping and I want to add in each group sum of values from column to make it to look like this https://leeontech.files.wordpress.com/2010/02/final.png
I have try to use many solutions from internet but nothing work for me:
My XML
<DataGrid x:Name="GridRaport" CanUserAddRows="False" VerticalAlignment="Stretch" MinWidth="500" AlternatingRowBackground="LightBlue" AlternationCount="2" Margin="20,20,20,20">
<DataGrid.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<StackPanel >
<StackPanel Orientation="Horizontal">
<TextBlock Margin="10,10,10,10" Text="{Binding Name}" FontWeight="Bold" />
<TextBlock Margin="30,10,10,10" Text="{Binding ItemCount, StringFormat=Liczba wycieczek: {0}}" FontWeight="Bold" />
</StackPanel>
<ItemsPresenter />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>
</DataGrid>
And my Code behind
private void FillGridRaport()
{
string CmdString = string.Empty;
using (SqlConnection con = new SqlConnection(ConString))
{
CmdString = "Long query";
SqlCommand cmd = new SqlCommand(CmdString, con);
SqlDataAdapter sda = new SqlDataAdapter(cmd);
DataTable dt = new DataTable("Wycieczki");
sda.Fill(dt);
DataView dataView = dt.AsDataView();
BindingListCollectionView cv = CollectionViewSource.GetDefaultView(dataView) as BindingListCollectionView;
PropertyGroupDescription groupDescription1 = new PropertyGroupDescription();
groupDescription1.PropertyName = "Pracownik";
cv.GroupDescriptions.Add(groupDescription1);
GridRaport.ItemsSource = cv;
}
}
I will be weary grateful for your help
Upvotes: 1
Views: 1387
Reputation: 4322
To get the sum, you need a converter. Make a class that implements IValueConverter, add it as a resource with a key and then reference it in the XAML.
Here is an example converter, I have it setup to take the field name as the ConverterParameter.
public class SumValues : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var cvg = value as CollectionViewGroup;
var field = parameter as string;
if (cvg == null || field == null)
return null;
// Double field
return cvg.Items.Sum(r => (double)(r as DataRowView)[field]);
// Or, if the field is nullable
//return cvg.Items.Sum(r => (r as DataRowView)[field] as double?); // "as" can return null so we have to use "double?"
// More complex example - string field that needs to be converted to a long
//return cvg.Items.Sum(r => long.Parse((r as DataRowView)[field].ToString()));
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Add the converter as a resource, either in App.xaml or locally to the DataGrid:
<DataGrid.Resources>
<local:SumValues x:Key="SumValues" />
</DataGrid.Resources>
And, finally, add the textblock to your GroupItem's ControlTemplate:
<TextBlock Margin="60,10,10,10" Text="{Binding StringFormat=Sum: {0}, Converter={StaticResource SumValues}, ConverterParameter=MyDataSetFieldName}" FontWeight="Bold" />
Upvotes: 4