I have a Telerik RadGridView Bound to ObservableCollection of defined type.. On Updating the value of a particular property in that type, the corresponding RadGridView cells are getting updated but not the total in the footer..i have created the dependency property for the same, but getting error: Set property 'System.Windows.Setter.Property' threw an exception.
Below is the XAML:
<ComboBox Grid.Column="4" Width="100" Margin="4" ItemsSource="{Binding Path=ResultUnits, Mode=OneTime}" SelectedValue="{Binding Path=ResultUnit}"/>
<telerik:RadGridView ItemsSource="{Binding Path=Results, Mode=TwoWay}" FooterRowStyle="{StaticResource GridViewFooterStyle}" Width="{Binding RelativeSource={RelativeSource AncestorType= ScrollViewer}, Path=ActualWidth}" ColumnWidth="*" RowIndicatorVisibility="Collapsed" EditTriggers="None" IsFilteringAllowed="False" AutoGenerateColumns="False" AllowDrop="False" CanUserFreezeColumns="False" CanUserReorderColumns="False" CanUserDeleteRows="False" CanUserInsertRows="False" ShowGroupPanel="False" ShowColumnFooters="True">
<telerik:RadGridView.Resources>
<Style TargetType="{x:Type telerik:RadGridView}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.UpdateFooter}" Value="True">
<Setter Property="my:UpdateGridViewFooter.HandleGridViewUpdateFooterProperty" Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
</telerik:RadGridView.Resources>
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn Header="Quantity" DataMemberBinding="{Binding Path=Quantity}">
<telerik:GridViewColumn.AggregateFunctions>
<telerikData:SumFunction SourceField="Weight"/>
</telerik:GridViewColumn.AggregateFunctions>
</telerik:GridViewDataColumn>
</telerik:RadGridView.Columns>
</telerik:RadGridView>
Below is the View Model Code:
public class ViewModel {
private const decimal PoundsToKilograms = 0.45359237M;
private const decimal GramstoPound = 0.00220462262M;
private ObservableCollection<Result> results;
public EnvironmentalSummaryViewModel() {
this.results= new ObservableCollection<Result>();
}
public ObservableCollection<Result> Results{
get {
return this.results;
}
set {
this.results = value;
}
}
public string ResultUnit {
get {
return this.resultUnit;
}
set {
if (this.resultUnit != value) {
this.resultUnit = value;
this.UpdateGridViewValuesOnResultUnitChanged();
}
}
}
public bool UpdateFooter { get; set; }
private void UpdateGridViewValuesOnResultUnitChanged() {
bool isEnglish = this.resultUnit == this.resultUnits[0];
this.results.ToList().ForEach(result => {
decimal weight = isEnglish ? result.Weight * GramstoPound * 1000 : environmental.Weight * PoundsToKilograms;
result.Weight = Math.Round(weight, 2);
});
}
this.UpdateFooter = true;
}
Object Class:
public class Result{
private decimal weight;
public decimal Weight {
get { return this.weight;}
set { this.weight = value;
((IHaveOnPropertyChangedMethod) this).OnPropertyChanged("Weight");
}
}
}
Dependency Property:
public static class UpdateGridViewFooter {
/// <summary>
/// Handle GridView Footer Update Attached Dependency Property
/// </summary>
public static readonly DependencyProperty HandleGridViewUpdateFooterProperty =
DependencyProperty.RegisterAttached(
"HandleGridViewUpdateFooter",
typeof(bool),
typeof(UpdateGridViewFooter),
new FrameworkPropertyMetadata(false, new PropertyChangedCallback(UpdateFooterOnValueChanged)));
/// <summary>
/// Gets the GridView Footer Update property.
/// </summary>
/// <param name="d">The DependencyObject</param>
/// <returns>The bool value</returns>
public static bool GetHandleGridViewUpdateFooterProperty(DependencyObject d) {
return (bool) d.GetValue(HandleGridViewUpdateFooterProperty);
}
/// <summary>
/// Sets the GridView Footer Update property.
/// </summary>
/// <param name="d">The DependencyObject</param>
/// <param name="value">The bool value</param>
public static void SetHandleGridViewUpdateFooterProperty(DependencyObject d, bool value) {
d.SetValue(HandleGridViewUpdateFooterProperty, value);
}
public static void UpdateFooterOnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
var radGridView = d as RadGridView;
if (radGridView != null) {
radGridView.CalculateAggregates();
}
}
}
I faced the same problem today, i.e. the total in the
RadGridViewis not updated when theViewModelis changed.I implemented an event in the
ViewModelinstead, e.g.ResultChanged, and added an event listener in the code behind of the view which callsCalculateAggregates(). Not a very elegant solution, but it works.