I'm overriding the SummaryResultPresenter's Control Template in a XamDataGrid in order to set the background color of the summary grouped rows. If the grid's RecordContainerGenerationMode is set to Recycle, the background colors don't always color correctly while scrolling. If I set the RecordContainerGenerationMode to Virtualize then everything works correctly.
The problem with this is that the performance of Virtualize mode is not as good as Recycle. Is there any way to set the RecordContainerGenerationMode to Recycle and have the coloring show correctly while scrolling?
Hello Andrew,
Are you binding the background to some property? If so have you verified that change notifications are indeed firing when scrolling?
The performance you are seeing with "Virtualize" is to be expected because the elements are created lazily which I would avoid if possible.
However, I recommend setting the FilterEvaluationMode to UseCollectionView to counter this behavior.
Let me know if you have any questions.
We already are setting the FilterEvaluationMode to UseCollectionView.
Here's the code we use to override the background. Again, everything works as expected with "Virtualize" but not with "Recycle".
<Style TargetType="{x:Type igData:SummaryResultPresenter}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type igData:SummaryResultPresenter}"> <Border Background="{Binding Converter={StaticResource SummaryFieldBackgroundToColorConverter}}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0" Margin="0,0,0,0" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True" ToolTip="{Binding Path=SummaryResult.ToolTipResolved, RelativeSource={RelativeSource TemplatedParent}}"> <TextBlock HorizontalAlignment="Right" Foreground="{Binding Converter={StaticResource SummaryFieldForegroundToColorConverter}}" Text="{Binding Path=SummaryResult.DisplayTextAsync, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"/> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style>
And here's our converter code
public class SummaryBackgroundFieldToColorConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value == null) return null; var summaryResultEntry = value as SummaryResultEntry; var summaryValue = summaryResultEntry?.SummaryResult.Value; if (summaryValue == null) return null; double dblValue; if (!double.TryParse(summaryValue.ToString(), out dblValue) || dblValue == 0) { return null; } return dblValue < 0 ? Brushes.Red : Brushes.Green; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return value; } }
I attached a sample that uses your converter and binds to the background of the SummaryResultPresenter. The only difference was I had to use a SolidColorBrush to show the color otherwise it wouldn't work. Scrolling works as expected. Please review my sample, located here, and modify it accordingly to reproduce the behavior.
In your example, make the following changes and then when you run it, group by "OrderID" and you should see how the averaged summation back colors aren't always correct. Values over 50 should always be red but they aren't. If you set the grid to "Virtualize", then the colors are always correct.
Here's the SummaryResultPresenter Style
<Style TargetType="{x:Type igDP:SummaryResultPresenter}"> <Setter Property="Padding" Value="1,1"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type igDP:SummaryResultPresenter}"> <Border Background="{Binding Converter={StaticResource bconverter}}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1" Padding="{TemplateBinding Padding}" ToolTip="{Binding Path=SummaryResult.ToolTipResolved, RelativeSource={RelativeSource TemplatedParent}}"> <!-- SSP 3/19/10 - Optimizations Changed the binding to bind to the new DisplayTextAsync instead of the DisplayText so we don't force synchronous calculation of the summary if it's dirty. --> <TextBlock Text="{Binding Path=SummaryResult.DisplayTextAsync, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"/> </Border> </ControlTemplate> </Setter.Value> </Setter> <Setter Property="Margin" Value="0,0,0,2"/> </Style>
Here's the mainWindow Load Event (with some xamdatagrid settings)
private void Window_Loaded(object sender, RoutedEventArgs e) { NwindDataSet nwind = new NwindDataSet(); NwindDataSetTableAdapters.OrdersTableAdapter ord = new NwindDataSetTableAdapters.OrdersTableAdapter(); ord.Fill(nwind.Orders); NwindDataSetTableAdapters.Order_DetailsTableAdapter ordd = new NwindDataSetTableAdapters.Order_DetailsTableAdapter(); ordd.Fill(nwind.Order_Details); xamDataGrid1.DataSource = nwind.Orders.DefaultView; xamDataGrid1.FieldSettings.SummaryDisplayArea = SummaryDisplayAreas.InGroupByRecords; xamDataGrid1.FieldSettings.SummaryUIType = SummaryUIType.MultiSelect; xamDataGrid1.FieldLayoutSettings.GroupBySummaryDisplayMode = GroupBySummaryDisplayMode.SummaryCellsAlwaysBelowDescription; xamDataGrid1.FieldSettings.AllowEdit = false; loadSummary(); }
Here's the Convert Method
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (value == null) return null; var summaryResultEntry = value as SummaryResultEntry; var summaryValue = summaryResultEntry?.SummaryResult.Value; if (summaryValue == null) return null; double dblValue; if (!double.TryParse(summaryValue.ToString(), out dblValue)) { return null; } return dblValue > 50 ? "red" : "blue"; }
I retested my sample with version 12.1 and everything is working as expected. However the loaded event code is causing the summary row to no longer appear because you have SummaryDisplayAreas set to InGroupByRecords, thus the element you would be interested in styling would be called GroupBySummariesPresenter.
If you change SummaryDisplayAreas to "TOP", and groupby OrderID and expand the child bands then the converter is working as expected along with the modified XAML.
Are you trying to style the summaries when they're located inside the GroupbySummariesPresenter?
Yes, each Group Row should have a summary. That's why SummaryDisplayArea is set to "InGroupByRecords". When you run the sample with my changes, expand the main window out width wise and you'll see that each group row does have a summary and it is colored just not always correctly.
Background="{Binding Path=SummaryResult.Value, Converter={StaticResource bconverter}}" if (value != null) { if ((decimal)value > 33) { return new SolidColorBrush(Colors.Red); } else { return new SolidColorBrush(Colors.Blue); } } { return null; }
YES!! That fixes it. Thanks so much Michael.