Пример #1
0
        private int AddItemToGroup(GroupByKey key, int rowIndex, out bool notify)
        {
            notify = false;
            List <int> rowsInGroup;
            int        groupedIndex;

            if (_groupedRows.TryGetValue(key, out rowsInGroup))
            {
                groupedIndex = _keyPositions[key];
                rowsInGroup.Add(rowIndex);
            }
            else
            {
                rowsInGroup  = new List <int>();
                groupedIndex = _groupedRows.AddWithIndex(key, rowsInGroup);
                _keyPositions.Add(key, groupedIndex);
                rowsInGroup.Add(rowIndex);
                foreach (var aggregateColumn in _aggregateColumns)
                {
                    aggregateColumn.AddField(groupedIndex);
                }

                notify = true;
                // Make sure all the column values are sent too
                foreach (var keyColumn in _keyColumns)
                {
                    _updates.OnNext(TableUpdate.NewColumnUpdate(groupedIndex, (IReactiveColumn)keyColumn));
                }
            }
            return(groupedIndex);
        }
Пример #2
0
        private bool RemoveItemFromGroup(List <int> @group, int rowIndex, GroupByKey key, int groupedIndex)
        {
            group.Remove(rowIndex);
            var notifyRequired = RemoveEmptyGroup(group, key, groupedIndex);

            foreach (var aggregateColumn in _aggregateColumns)
            {
                aggregateColumn.RemoveOldValue(rowIndex, groupedIndex);
            }
            return(notifyRequired);
        }
Пример #3
0
        private bool RemoveEmptyGroup(List <int> @group, GroupByKey key, int groupedIndex)
        {
            if (group.Count == 0)
            {
                // Remove the group
                _groupedRows.RemoveAt(groupedIndex);
//                _groupedRows.Remove(key);
                _keyPositions.Remove(key);

                // Remove the field from the aggregate column
                foreach (var aggregateColumn in _aggregateColumns)
                {
                    aggregateColumn.RemoveField(groupedIndex);
                }

                return(true);
            }
            return(false);
        }
Пример #4
0
        private void OnSourceValue(TableUpdate tableUpdate)
        {
            var columnUpdated = tableUpdate.Column;
            var sourceIndex   = tableUpdate.RowIndex;
            int groupedIndex;
            var groupChanged = false;

            if (tableUpdate.Action == TableUpdateAction.Add)
            {
                // New source row added
                var  key = new GroupByKey(_keyColumns, sourceIndex);
                bool notifyOfAdd;
                groupedIndex = AddItemToGroup(key, sourceIndex, out notifyOfAdd);
                if (notifyOfAdd)
                {
                    NotifyOfGroupAdd(groupedIndex);
                }
                _sourceRowsToKeys.Add(sourceIndex, key);
                groupChanged = true;
            }
            else if (tableUpdate.Action == TableUpdateAction.Delete)
            {
                // Source row deleted
                var key   = _sourceRowsToKeys[sourceIndex];
                var group = _groupedRows[key];
                groupedIndex = _keyPositions[key];

                if (RemoveItemFromGroup(@group, sourceIndex, key, groupedIndex))
                {
                    NotifyOfGroupDelete(groupedIndex);
                }

                _sourceRowsToKeys.Remove(sourceIndex);
                groupChanged = true;
            }
            else if (tableUpdate.Action == TableUpdateAction.Update &&
                     _groupColumns.ContainsKey(columnUpdated.ColumnId))
            {
                // Source row changing group
                var key = _sourceRowsToKeys[sourceIndex];
                // TODO: figure out how to do this without allocations
                var newKey = new GroupByKey(_keyColumns, sourceIndex);

                // Move the rowIndex from the old key to the new key
                var  group          = _groupedRows[key];
                var  oldGroupIndex  = _keyPositions[key];
                var  notifyOfDelete = RemoveItemFromGroup(@group, sourceIndex, key, oldGroupIndex);
                bool notifyOfAdd;
                groupedIndex = AddItemToGroup(newKey, sourceIndex, out notifyOfAdd);
                NotifyOnGroupChange(notifyOfAdd, notifyOfDelete, oldGroupIndex, groupedIndex);

                // Replace the rowIndex to key mapping
                _sourceRowsToKeys[sourceIndex] = newKey;

                var column = FindKeyColumn(columnUpdated.ColumnId, _keyColumns);
                column.NotifyObserversOnNext(groupedIndex);
                _updates.OnNext(TableUpdate.NewColumnUpdate(groupedIndex, (IReactiveColumn)column));
//                Console.WriteLine("Grouped column updated");
                groupChanged = true;
            }
            else
            {
                var key = _sourceRowsToKeys[sourceIndex];
                groupedIndex = _keyPositions[key];
//                Console.WriteLine("Non grouped column updated");
            }

            // Aggregated column has changed or group changed which forces re-calc.
            foreach (var aggregateColumn in _aggregateColumns)
            {
                if (groupChanged ||
                    tableUpdate.Column.ColumnId == aggregateColumn.SourceColumn.ColumnId)
                {
                    aggregateColumn.ProcessValue(sourceIndex, groupedIndex);
                    _updates.OnNext(TableUpdate.NewColumnUpdate(groupedIndex, aggregateColumn));
                }
            }
        }