/// <summary>
        /// Overridden to enable undoing paste actions.
        /// </summary>
        public override void Paste()
        {
            // paste into active editor, if any
            var tb = GetActiveTextBox();
            if (tb != null)
            {
                // note: setting SelectedText doesn't work with binding
                // looks like a bug in the TextBox control.
                var clip = System.Windows.Clipboard.GetText();
                var txt = tb.Text;
                var ss = tb.SelectionStart;
                var sl = tb.SelectionLength;
                tb.Text = txt.Substring(0, ss) + clip + txt.Substring(ss + sl);
                tb.Select(ss, clip.Length);
                tb.Focus();
                return;
            }

            // create undoable paste action to represent this paste operation
            _pasteAction = new PasteAction(this);

            // perform the paste operation
            // (all flex[r,c] will be recorded while _pasteAction != null)
            base.Paste();

            // close the paste action and add to the undo stack
            if (_pasteAction.SaveNewState())
            {
                _undo.AddAction(_pasteAction);
            }
            _pasteAction = null;
        }
        /// <summary>
        /// Clears all nullable/editable cells in a given range.
        /// </summary>
        public void ClearRange(CellRange range)
        {
            if (!IsReadOnly)
            {
                // create undoable paste action to represent this clear operation
                _pasteAction = new PasteAction(this);

                // clear selected cells
                var invalidate = false;
                foreach (var cell in range.Cells)
                {
                    if (AllowEditing(cell.Row, cell.Column))
                    {
                        this[cell.Row, cell.Column] = null;
                        invalidate |= this.Columns[cell.Column].GroupAggregate != Aggregate.None;
                    }
                }

                // if the range that was cleared contains aggregates,
                // invalidate grid to force an update
                if (invalidate)
                {
                    Invalidate();
                }

                // close the paste action and add to the undo stack
                if (_pasteAction.SaveNewState())
                {
                    UndoStack.AddAction(_pasteAction);
                }
                _pasteAction = null;
            }
        }