Correct way to get sum from CollectionView

Posted by: fernando on 23 October 2017, 12:32 pm EST

  • Posted 23 October 2017, 12:32 pm EST

    Hi

    Maybe i’m not getting something, but i have a CollectionView being used with an ObservableCollection

    This CollectionView gets applied a series of filters to show the information and i want to have a Label with the Sum of certain column. Everytime a filter is applied to the Collection, the column will update with its current Sum

    That’s where the problems occurs, i’m subscribing to the collection FilterChanged event and inside i calculate the sum as follows:

    Totals = CollectionView.Sum(x => ((InventoryItem)x).Qty);
    

    But it seems that i’m always getting the sum of the “previous” filter condition…

    Example:

    I have 3 filters to apply (inside a Picker), everytime i pick one, a filter applies… the first time the sum fires, it is getting the sum of ALL the items in the collection (it is not taking only the filtered ones)… so if i change the filter again, now the Sum shows the previous filter…

    I don’t know if i’m explaining myself correctly, and i do not know if it is an issue with my code or with the CollectionView, o maybe there is other what of getting the current value or sum of what the CollectionView is showing at the moment

  • Posted 23 October 2017, 1:43 pm EST

    Is as if the CollectionView is giving be the sum BEFORE the Filter is Applied, before the CollectionView updates itself

  • Posted 25 October 2017, 5:11 am EST

    Hi Fernando

    I’m not sure I’m immediately seeing a problem on my end. What platform are you working with and can you share a little more of your code?

    Thanks

    Kelley

  • Posted 25 October 2017, 9:23 pm EST

    Thanks Kelley

    I’m using Xamarin.Forms, currently testing in a iOS project

    In my GetData method, i’m filling my CollectionView as follows: (code shorted for exampling purposes)

    Items is just an ObservableCollection

    
    this.CollectionView = new C1CollectionView<InventoryItem>(Items); this.CollectionView.FilterChanged += CollectionView_FilterChanged;
    RecalculateTotals();
    
    
    
         void CollectionView_FilterChanged(object sender, EventArgs e)
            {
                Totals = CollectionView.Sum(x => ((InventoryItem)x).OrderQty);
            }
    
    

    the First time I load my ObservableCollection (without filter, using the RecalculateTotals() method), i’m Getting the Sum of the CollectionView and it displays the Sum correctly, then AFTER i change the filter, example:

    
    CollectionView.FilterAsync(x => x.Product, FilterOperation.Contains, "Cuke");
    
    

    The CollectionView correctly updates and shows the filtered elements, its FilteredChanged events fires BUT my Totals aren’t changed, AFTER i change the Filter for a second time, the Totals updates, but now they do not represent what the CollectionView is showing (they show the Sum of the previous Filtered Items)

    Currently i’m using C1.Forms.Xamarin version 2.3.20172.189

  • Posted 26 October 2017, 8:38 am EST

    Hi Fernando

    Are you awaiting your FilterAsync operation? It sounds like that might be the issue based on your description.

    Kelley

  • Posted 26 October 2017, 8:59 pm EST

    It is not working even with the await

    In my getData() Task:

    
    //My binded property Totals = 0 at this point
     this.CollectionView = new C1CollectionView<InventoryItem>(Items);
     this.CollectionView.FilterChanged += CollectionView_FilterChanged;
    RecalculateTotals(); //Here i calculate the totals without any filter, it returns 1000 or so
     await Task.Delay(2500);
     await CollectionView.FilterAsync(x => x.Product, FilterOperation.Contains, "Cuke");
    //At this point, the Filter event is called, inside i just calculate the Totals again
    
    

    After the Task.Delay, the FlexGrid is correctly applying the filter and showing the filtered elements BUT the Totals arent updating

    NOTE: If i add a second filter just below the .FilterAsync above:

    
    await Task.Delay(2500);
    await CollectionView.FilterAsync(x => x.Product, FilterOperation.Contains, "Bell");
    
    

    Now it updates the FlexGrid AND the Totals, but now, the Grid is showing my “Bell” Product, but the Totals are the ones for the “Cuke” filter

  • Posted 1 November 2017, 9:38 pm EST

    Bump! :frowning:

  • Posted 2 November 2017, 12:54 am EST

    Hi Fernando

    I’m sorry it’s not clear from your code where the issue is. I modified the “Filter” sample in FlexGrid101 to do something like you’ve described. You can find it here:

    http://publicfiles.componentone.com/Kelley/FlexGrid101.zip

    I’ve added a total label to the display, and I’m filtering the FlexGrid based on what the user input in the filter form. In the constructor, I’m giving the grid and label data:

                var data = Customer.GetCustomerList(100);
                grid.ItemsSource = data;
                total.Text = ((C1CollectionView<object>)grid.CollectionView).Sum(x => ((Customer)x).OrderTotal).ToString();
                ((C1CollectionView<object>)grid.CollectionView).FilterChanged += Cv_FilterChanged;
    

    And I’m firing this event once the user changes the filter:

            private void Cv_FilterChanged(object sender, EventArgs e)
            {
                total.Text = ((C1CollectionView<object>)grid.CollectionView).Sum(x => ((Customer)x).OrderTotal).ToString();
            }
    

    Hopefully that helps. I don’t see any issues with the controls so it must be something in your implementation.

    Kelley

Need extra support?

Upgrade your support plan and get personal unlimited phone support with our customer engagement team

Learn More

Forum Channels