Reputation: 1147
I'd like to show the average score in each group. I think I need to add a converter in the control template, actually I don't how does it work.
<DataGrid Name="dataGrid1" ItemsSource="{Binding List}" AutoGenerateColumns="True" Grid.ColumnSpan="4" Grid.RowSpan="21">
<DataGrid.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=Name}" FontWeight="Bold" Padding="3"/>
</StackPanel>
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander>
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}" />
<TextBlock Text="{Binding Path=ItemCount}" Margin="8,0,4,0"/>
<TextBlock Text="Items" Margin="8,0,4,0"/>
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>
</DataGrid>
This the code an example code which I'm doing tests:
public enum KindOfPerson
{
Student, Teacher, ...
}
public class Person
{
// This contains only numbers between 0 and 1
public double ScorePercent { get; set; }
public KindOfPerson Type { get; set; }
}
I'm groupping by KindOfPerson
Upvotes: 0
Views: 143
Reputation: 184376
You can indeed use a converter, here would be an example:
<!-- The additional binding to ItemsCount is used to get the binding updated if new items are added, maybe there is a cleaner and easier way -->
<TextBlock>
<TextBlock.Text>
<MultiBinding>
<MultiBinding.Converter>
<vc:MeanConverter PropertyName="ScorePercent" />
</MultiBinding.Converter>
<Binding Path="Items" />
<Binding Path="ItemCount" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
// Note that this code might be quite the crap, it's just a sketchy example implementation.
public class MeanConverter : IMultiValueConverter
{
/// <summary>
/// Name of the property which should be evaluated.
/// </summary>
public string PropertyName { get; set; }
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var items = values[0] as ReadOnlyObservableCollection<object>;
double accscore = 0;
PropertyInfo property = null;
foreach (var item in items)
{
if (property == null)
{
property = item.GetType().GetProperty(PropertyName);
}
var value = property.GetValue(item, null);
accscore += (double)System.Convert.ChangeType(value, typeof(double));
}
var output = accscore/items.Count;
return output.ToString();
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
Upvotes: 1