Home > Back-end >  Refreshing DataGrid causes NullReferenceException
Refreshing DataGrid causes NullReferenceException

Time:06-02

I have a DataGrid:

<DataGrid Style="{StaticResource MaterialDesignDataGrid}" ItemsSource="{Binding AllSales, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}" x:Name="salesData"
                  materialDesign:DataGridAssist.CellPadding="5" Background="White" GridLinesVisibility="All" 
                  VerticalGridLinesBrush="LightGray" HorizontalGridLinesBrush="LightGray" BorderThickness="0.1"
                  CanUserDeleteRows="False" CanUserReorderColumns="False" CanUserResizeRows="False" CanUserSortColumns="False" Cursor="Arrow"
                  CanUserResizeColumns="False" CanUserAddRows="False" ColumnWidth="*" AutoGenerateColumns="False" d:ItemsSource="{d:SampleData ItemCount=5}" >

that is populated by retrieving data from backend:

private async void searchFilter_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            salesVM.DashBoardVM.IsLoading = true;
            int idDepartment = salesVM.DashBoardVM.MainVM.Device.IdDepartment;
            string from = fromDateTxt.Text;
            string to = toDateTxt.Text;
            var filter = salesVM.SimpleFilterViewModel;
            salesVM.AllSales.Clear();
            //salesData.Items.Refresh();
            var report = await Task.Run(() => salesVM.DashBoardVM.MainVM.APIService.Reports.SalesReport(idDepartment, from, to, filter.SelectedCategoryIds, filter.SelectedGroupIds));
            if (report != null)
            {
                if (report.Sales != null)
                {
                    salesVM.AllSales.AddRange(report.Sales);
                    //salesData.Items.Refresh();
                    ICollectionView collectionView = CollectionViewSource.GetDefaultView(salesData.ItemsSource);
                    if (collectionView != null && collectionView.CanGroup == true)
                    {
                        collectionView.GroupDescriptions.Clear();
                        collectionView.GroupDescriptions.Add(new PropertyGroupDescription("CategoryName"));
                    }
                }
            }
            salesVM.DashBoardVM.IsLoading = false;
        }
        catch (Exception ex)
        {

        }
    }

Binded property is:

private ObservableCollection<Sale> allSales;
    public ObservableCollection<Sale> AllSales
    {
        get { return allSales; }
        set
        {
            allSales = value;
            OnPropertyChanged(new PropertyChangedEventArgs("AllSales"));
        }
    }

When I retrieve data several times (usually 1-2) it works perfectly. After 3rd time when I want to clear grid, while retrieving new data it throws a NullReferenceException when resetting collection on line:

salesVM.AllSales.Clear()

AllSales is never null, initially empty. StackTrace is:

       at System.Windows.StyleHelper.UpdateTables(PropertyValue& propertyValue, FrugalStructList`1& childRecordFromChildIndex, FrugalStructList`1& triggerSourceRecordFromChildIndex, FrugalStructList`1& resourceDependents, HybridDictionary& dataTriggerRecordFromBinding, HybridDictionary childIndexFromChildName, Boolean& hasInstanceValues)
   at System.Windows.TemplateContent.ParseXaml()
   at System.Windows.FrameworkTemplate.set_Template(TemplateContent value)
   at System.Windows.Baml2006.WpfSharedBamlSchemaContext.<>c.<Create_BamlProperty_FrameworkTemplate_Template>b__277_0(Object target, Object value)
   at System.Windows.Baml2006.WpfKnownMemberInvoker.SetValue(Object instance, Object value)
   at MS.Internal.Xaml.Runtime.ClrObjectRuntime.SetValue(XamlMember member, Object obj, Object value)
   at MS.Internal.Xaml.Runtime.ClrObjectRuntime.SetValue(Object inst, XamlMember property, Object value)
   at MS.Internal.Xaml.Runtime.PartialTrustTolerantRuntime.SetValue(Object obj, XamlMember property, Object value)
   at System.Xaml.XamlObjectWriter.Logic_ApplyPropertyValue(ObjectWriterContext ctx, XamlMember prop, Object value, Boolean onParent)
   at System.Xaml.XamlObjectWriter.Logic_DoAssignmentToParentProperty(ObjectWriterContext ctx)
   at System.Xaml.XamlObjectWriter.WriteEndMember()
   at System.Xaml.XamlWriter.WriteNode(XamlReader reader)
   at System.Windows.Markup.WpfXamlLoader.TransformNodes(XamlReader xamlReader, XamlObjectWriter xamlWriter, Boolean onlyLoadOneNode, Boolean skipJournaledProperties, Boolean shouldPassLineNumberInfo, IXamlLineInfo xamlLineInfo, IXamlLineInfoConsumer xamlLineInfoConsumer, XamlContextStack`1 stack, IStyleConnector styleConnector)
   at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
   at System.Windows.Markup.WpfXamlLoader.LoadDeferredContent(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings parentSettings, Uri baseUri)
   at System.Windows.ResourceDictionary.CreateObject(KeyRecord key)
   at System.Windows.ResourceDictionary.OnGettingValue(Object key, Object& value, Boolean& canCache)
   at System.Windows.ResourceDictionary.OnGettingValuePrivate(Object key, Object& value, Boolean& canCache)
   at System.Windows.ResourceDictionary.GetValueWithoutLock(Object key, Boolean& canCache)
   at System.Windows.ResourceDictionary.GetValue(Object key, Boolean& canCache)
   at System.Windows.DeferredResourceReference.GetValue(BaseValueSourceInternal valueSource)
   at System.Windows.DeferredAppResourceReference.GetValue(BaseValueSourceInternal valueSource)
   at System.Windows.StaticResourceExtension.TryProvideValueImpl(IServiceProvider serviceProvider, Boolean allowDeferredReference, Boolean mustReturnDeferredResourceReference)
   at System.Windows.StaticResourceExtension.ProvideValueInternal(IServiceProvider serviceProvider, Boolean allowDeferredReference)
   at System.Windows.StaticResourceExtension.ProvideValue(IServiceProvider serviceProvider)
   at MS.Internal.Xaml.Runtime.ClrObjectRuntime.CallProvideValue(MarkupExtension me, IServiceProvider serviceProvider)
   at MS.Internal.Xaml.Runtime.PartialTrustTolerantRuntime.CallProvideValue(MarkupExtension me, IServiceProvider serviceProvider)
   at System.Xaml.XamlObjectWriter.Logic_ProvideValue(ObjectWriterContext ctx)
   at System.Xaml.XamlObjectWriter.Logic_AssignProvidedValue(ObjectWriterContext ctx)
   at System.Xaml.XamlObjectWriter.WriteEndMember()
   at System.Xaml.XamlWriter.WriteNode(XamlReader reader)
   at System.Windows.Markup.WpfXamlLoader.TransformNodes(XamlReader xamlReader, XamlObjectWriter xamlWriter, Boolean onlyLoadOneNode, Boolean skipJournaledProperties, Boolean shouldPassLineNumberInfo, IXamlLineInfo xamlLineInfo, IXamlLineInfoConsumer xamlLineInfoConsumer, XamlContextStack`1 stack, IStyleConnector styleConnector)
   at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
   at System.Windows.Markup.WpfXamlLoader.LoadDeferredContent(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings parentSettings, Uri baseUri)
   at System.Windows.ResourceDictionary.CreateObject(KeyRecord key)
   at System.Windows.ResourceDictionary.OnGettingValue(Object key, Object& value, Boolean& canCache)
   at System.Windows.ResourceDictionary.OnGettingValuePrivate(Object key, Object& value, Boolean& canCache)
   at System.Windows.ResourceDictionary.GetValueWithoutLock(Object key, Boolean& canCache)
   at System.Windows.ResourceDictionary.GetValue(Object key, Boolean& canCache)
   at System.Windows.ResourceDictionary.FetchResource(Object resourceKey, Boolean allowDeferredResourceReference, Boolean mustReturnDeferredResourceReference, Boolean canCacheAsThemeResource, Boolean& canCache)
   at System.Windows.FrameworkElement.FindResourceInternal(FrameworkElement fe, FrameworkContentElement fce, DependencyProperty dp, Object resourceKey, Object unlinkedParent, Boolean allowDeferredResourceReference, Boolean mustReturnDeferredResourceReference, DependencyObject boundaryElement, Boolean isImplicitStyleLookup, Object& source)
   at System.Windows.FrameworkElement.FindImplicitStyleResource(FrameworkElement fe, Object resourceKey, Object& source)
   at System.Windows.FrameworkElement.GetRawValue(DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry& entry)
   at System.Windows.FrameworkElement.EvaluateBaseValueCore(DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry& newEntry)
   at System.Windows.DependencyObject.EvaluateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry newEntry, OperationType operationType)
   at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
   at System.Windows.DependencyObject.InvalidateProperty(DependencyProperty dp, Boolean preserveCurrentValue)
   at System.Windows.FrameworkElement.UpdateStyleProperty()
   at System.Windows.TreeWalkHelper.InvalidateStyleAndReferences(DependencyObject d, ResourcesChangeInfo info, Boolean containsTypeOfKey)
   at System.Windows.TreeWalkHelper.OnResourcesChanged(DependencyObject d, ResourcesChangeInfo info, Boolean raiseResourceChangedEvent)
   at System.Windows.FrameworkElement.OnAncestorChangedInternal(TreeChangeInfo parentTreeState)
   at System.Windows.TreeWalkHelper.OnAncestorChanged(DependencyObject d, TreeChangeInfo info, Boolean visitedViaVisualTree)
   at System.Windows.DescendentsWalker`1._VisitNode(DependencyObject d, Boolean visitedViaVisualTree)
   at MS.Internal.PrePostDescendentsWalker`1._VisitNode(DependencyObject d, Boolean visitedViaVisualTree)
   at System.Windows.DescendentsWalker`1.VisitNode(FrameworkElement fe, Boolean visitedViaVisualTree)
   at System.Windows.DescendentsWalker`1.VisitNode(DependencyObject d, Boolean visitedViaVisualTree)
   at System.Windows.DescendentsWalker`1.WalkFrameworkElementLogicalThenVisualChildren(FrameworkElement feParent, Boolean hasLogicalChildren)
   at System.Windows.DescendentsWalker`1.IterateChildren(DependencyObject d)
   at System.Windows.DescendentsWalker`1.StartWalk(DependencyObject startNode, Boolean skipStartNode)
   at MS.Internal.PrePostDescendentsWalker`1.StartWalk(DependencyObject startNode, Boolean skipStartNode)
   at System.Windows.TreeWalkHelper.InvalidateOnTreeChange(FrameworkElement fe, FrameworkContentElement fce, DependencyObject parent, Boolean isAddOperation)
   at System.Windows.FrameworkElement.OnVisualParentChanged(DependencyObject oldParent)
   at System.Windows.Media.Visual.FireOnVisualParentChanged(DependencyObject oldParent)
   at System.Windows.Media.Visual.RemoveVisualChild(Visual child)
   at System.Windows.Media.VisualCollection.DisconnectChild(Int32 index)
   at System.Windows.Media.VisualCollection.Clear()
   at System.Windows.Controls.UIElementCollection.ClearInternal()
   at System.Windows.Controls.Panel.ClearChildren()
   at System.Windows.Controls.Panel.EnsureEmptyChildren(FrameworkElement logicalParent)
   at System.Windows.Controls.Panel.OnItemsChangedInternal(Object sender, ItemsChangedEventArgs args)
   at System.Windows.Controls.VirtualizingPanel.OnItemsChangedInternal(Object sender, ItemsChangedEventArgs args)
   at System.Windows.Controls.Panel.OnItemsChanged(Object sender, ItemsChangedEventArgs args)
   at System.Windows.Controls.ItemContainerGenerator.OnRefresh()
   at System.Windows.Controls.ItemContainerGenerator.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
   at System.Windows.WeakEventManager.ListenerList`1.DeliverEvent(Object sender, EventArgs e, Type managerType)
   at System.Windows.WeakEventManager.DeliverEvent(Object sender, EventArgs args)
   at System.Collections.Specialized.CollectionChangedEventManager.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
   at System.Collections.ObjectModel.ReadOnlyObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs args)
   at System.Collections.ObjectModel.ReadOnlyObservableCollection`1.HandleCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
   at System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
   at System.Collections.ObjectModel.ObservableCollection`1.ClearItems()
   at System.Collections.ObjectModel.Collection`1.Clear()
   at MS.Internal.Data.CollectionViewGroupInternal.Clear()
   at System.Windows.Data.ListCollectionView.PrepareShaping()
   at System.Windows.Data.ListCollectionView.PrepareLocalArray()
   at System.Windows.Data.ListCollectionView.RefreshOverride()
   at System.Windows.Data.CollectionView.RefreshInternal()
   at System.Windows.Data.CollectionView.RefreshOrDefer()
   at System.Windows.Data.ListCollectionView.ProcessCollectionChanged(NotifyCollectionChangedEventArgs args)
   at System.Windows.Data.CollectionView.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
   at System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
   at System.Collections.ObjectModel.ObservableCollection`1.ClearItems()
   at System.Collections.ObjectModel.Collection`1.Clear()
   at ReportApp.Views.Reports.Sales.SalesReportControl.<searchFilter_Click>d__13.MoveNext() in C:\Users\user\source\repos\ReportApp\Views\Reports\Sales\SalesReportControl.xaml.cs:line 261

Any help will be very much appreciated.

CodePudding user response:

Did not find exact reason, but fixed by changing datagrid grouping style from this:

<Expander x:Name="exp" IsExpanded="True" BorderBrush="DimGray" BorderThickness="0">
                                        <Expander.Header>
                                            <DockPanel>
                                                <TextBlock FontWeight="DemiBold" FontSize="18" Text="{Binding Path=Name}" />
                                            </DockPanel>
                                        </Expander.Header>
                                        <Expander.Content>
                                            <Grid>
                                                <Grid.RowDefinitions>
                                                    <RowDefinition/>
                                                    <RowDefinition/>
                                                </Grid.RowDefinitions>
                                                <ItemsPresenter />
                                                <TextBlock Grid.Row="1" Style="{StaticResource MaterialDesignBody2TextBlock}" FontSize="16" FontWeight="Normal" Padding="5" 
                                                       Text="{Binding Path=Items, Converter={StaticResource groupTotals}}" HorizontalAlignment="Right"/>
                                            </Grid>
                                        </Expander.Content>
                                    </Expander>

to this:

<Border BorderBrush="DimGray" BorderThickness="0">
                                        <Grid>
                                            <Grid.RowDefinitions>
                                                <RowDefinition/>
                                                <RowDefinition/>
                                            </Grid.RowDefinitions>
                                            <Grid Grid.Row="0">
                                                <TextBlock FontWeight="DemiBold" FontSize="18" Text="{Binding Path=Name}" Margin="10,0,0,0"/>
                                                <ToggleButton HorizontalAlignment="Right" Style="{StaticResource MaterialDesignExpanderToggleButton}" Margin="0,0,10,0" x:Name="toggle"
                                                              IsChecked="True">
                                                    <materialDesign:PackIcon Kind="ChevronDown"/>
                                                </ToggleButton>
                                            </Grid>
                                            <StackPanel Orientation="Vertical" Grid.Row="1" Visibility="{Binding ElementName=toggle, Path=IsChecked, Converter={StaticResource BooleanToVisibilityConverter}}">
                                                <ItemsPresenter />
                                                <TextBlock Grid.Row="1" Style="{StaticResource MaterialDesignBody2TextBlock}" FontSize="16" FontWeight="Normal" Padding="5" 
                                                       Text="{Binding Path=Items, Converter={StaticResource groupTotals}}" HorizontalAlignment="Right"/>
                                            </StackPanel>
                                        </Grid>
                                    </Border>
  • Related