views:

334

answers:

1

Does anyone know of a way to inject rows into a Silverlight DataGrid? I need a way to add totals rows after every 6 entries. The totals are for all rows above the summary row, not just the previous six.

I've tried doing it with grouping but that only shows the totals for the group and displays the totals rows above the actual rows. I would prefer to use a DataGrid for this if possible, but all solutions are welcome.

+1  A: 

Okay, I have a solution for you; however, it contains some funky math kung fu and so I am not sure whether it is the best solution. It does, however, work with a DataGrid.

public void PopulateAndSum()
    {

        //Ugly Math Kung Fu starts here
        //Get the number of rows in the collection
        int rowCount = Items.Count;

        //Here you specify after how many rows should the summation occur
        int numRowsToSum = 6;

        //Now the idea is to loop through the collection the same number of times
        //As you would be inserting summation rows into the collection
        //To calculate the maximum number of times you should circulate you
        //divide through the number of rows and ceil the result. Make sure
        //divide by a double or at least cast one of them to a double so you do
        //not get interger division
        for (int i = 0; i < Math.Ceiling(((double)rowCount) / numRowsToSum); i++)
        {
            //Now you want to calculate the position where you need to insert the the new entry
            int index = 0;

            //Check whether you are still in the bounds of the array or whether you have actually reached the last element
            //in the array. This should always be the case if your collection contains a multiple of numRowsToSum
            if (numRowsToSum + i * (numRowsToSum) <= rowCount)
            {
                //The index starts at numRowsToSum because you start the collection indexing at 0
                //From there you jump the next index and add one to take into account that you inserted a new element
                index = numRowsToSum + i*(numRowsToSum + 1);
            }
            else
            {
                //If your collection contains a number of elements that are not a precise multiple of numRowsToSum
                //then you have to have a special condition where you calculate the index for the last few elements
                //Here you need to jump back to the previous index and add the number of elements left in the collection
                //You also have to add 1 to take into account that you are adding an extra row.
                index = numRowsToSum + (i - 1) * (numRowsToSum + 1) + 1 + rowCount % numRowsToSum;
            }

            //Now you sum all the rows before the index

            int sum = 0;
            for (int j = 0; j < index; j++)
            {
                //If you want to add the previous totals to the sum comment the next part out
                if ((j - numRowsToSum) % (numRowsToSum + 1) == 0)
                    continue;

                sum += Items[j].Value;
            }

            //Now add the entry
            Items.Insert(index, new Info() { Name = "Total", Value = sum });
        }
    }

Items is an ObservableCollection and Info is just a test class I created. I did comment the code quite thoroughly. It is more generic than your requirement in the sense that you can change the numRowsToSum to any value and it should still work.

Johannes
I was hoping to find a solution that didn't require add directly to the bound collection, but I ended up doing something quite similar to this. Thanks for your help.
Stephan