Exemplo n.º 1
0
        private ViewPortState CalculateState()
        {
            Logger.Debug(GetType(),
                         "CalculateState()'s input HasRowHeightPx?={0} tbodyFactHeightPx={1} theadFactHeight={2} allItemsCount={3} rowHeightPx={4} topScrollPosPx={5}",
                         HasRowHeightPx,
                         _view.BodyVisibleSpace,
                         _view.HeaderVisibleSpace,
                         _model.Items.Length + _groups.Count * RowsPerGroupDescr,
                         RowHeightPx,
                         _view.ScrollPosition
                         );

            var result = new ViewPortState {
                RawScrollPos                = _view.ScrollPosition,
                PhysicalRowsCount           = _model.Items.Length,
                VirtualRowsCount            = _groups.Count * RowsPerGroupDescr,
                AllRowsCount                = _model.Items.Length + _groups.Count * RowsPerGroupDescr,
                TheoreticalVisibleRowsCount = (int)ComputeMaxVisibleRows(),
                FirstVisibleRow             = (int)ComputeFirstVisibleRow(),
                IncompleteLeadRowPad        = ComputeIncompleteLeadRowPad(),
                IncompleteBodyPad           = ComputeIncompleteBodyRowPad()
            };

            Logger.Debug(GetType(), "CalculateState()'s raw outcome={0}", result);

            if (result.FirstVisibleRow > result.AllRowsCount || result.FactVisibleRowsCount < 0)
            {
                //scroll is past data (probably many rows were deleted / grouping changed)
                result.IsInvalidScrollPos = true;

                if (result.AllRowsCount >= result.TheoreticalVisibleRowsCount)
                {
                    //will scroll to real bottom of new view
                    result.FirstVisibleRow = result.AllRowsCount - result.TheoreticalVisibleRowsCount;
                    result.RawScrollPos    = result.FirstVisibleRow * RowHeightPx;
                }
                else
                {
                    //will just move to beginning of table
                    result.FirstVisibleRow = 0;
                    result.RawScrollPos    = 0;
                }

                Logger.Debug(GetType(), "CalculateState()'s adjusted outcome={0}", result);
            }

            return(result);
        }
Exemplo n.º 2
0
        private void PopulateRows(bool itemsChanged, bool shouldRestoreScrollPosition = false)
        {
            var oldState = FormerState ?? ViewPortState.CreateEmpty();

            Logger.Debug(GetType(), "Former state: {0} shouldRestoreScrollPosition={1}", oldState, shouldRestoreScrollPosition);

            if (InitializeRowHeightIfNeededAndPossible())
            {
                UpdateTbodyHeight();
            }

            if (shouldRestoreScrollPosition && oldState.IsEmpty)
            {
                shouldRestoreScrollPosition = false;
            }

            var newState = shouldRestoreScrollPosition ? oldState : CalculateState();

            if (shouldRestoreScrollPosition || newState.IsInvalidScrollPos)
            {
                _view.ScrollPosition = oldState.RawScrollPos;
            }

            Logger.Debug(GetType(), "New state: {0}", newState);
            Logger.Debug(GetType(), "Scrolled progressed rows: {0} rowHeight={1}", newState.FirstVisibleRow - oldState.FirstVisibleRow, RowHeightPx);

            //see if any rows can be preserved by checking whether windows overlap
            var overlap = new Overlap(
                itemsChanged,
                oldState,
                newState);

            Logger.Debug(GetType(), "calculated overlap: {0}", overlap);



            //delete not overlapped leading rows (present in old BUT not present in new)
            if (overlap.ToPreTrim.IsNonEmpty)
            {
                Logger.Debug(GetType(), "overlap - removing unneccessary {0} leading rows", overlap.ToPreTrim.Length);
                for (var i = overlap.ToPreTrim.Length; i > 0; i--)
                {
                    DestroyRowAt(0);
                }
            }



            //delete not overlapped trailing rows
            if (overlap.ToPostTrim.IsNonEmpty)
            {
                Logger.Debug(GetType(), "overlap - removing unneccessary {0} trailing rows", overlap.ToPostTrim.Length);

                for (var i = overlap.ToPostTrim.Length; i > 0; i--)
                {
                    var pos = _view.BodyRowCount - 1;
                    DestroyRowAt(pos);
                }
            }



            //prepend not overlapped rows
            if (overlap.ToPrepend.IsNonEmpty)
            {
                Logger.Debug(GetType(), "overlap - prepending new {0} leading rows", overlap.ToPrepend.Length);
                var idx = 0;

                foreach (var item in EnumerateRecords(overlap.ToPrepend).AsEnumerable())
                {
                    switch (item.Item1)
                    {
                    case DataOrGroup.Data:
                        Logger.Debug(GetType(), "Prepending item {0}", item.Item2);
                        InsertRowFor(idx++, item.Item2);
                        break;

                    case DataOrGroup.Group:
                        Logger.Debug(GetType(), "Prepending group trailer for grp {0}", item.Item1);
                        InsertGroupTrailer(idx++, item.Item3);
                        break;

                    default: throw new Exception("unsupported DataOrGroup");
                    }
                }
            }



            //append not overlapped rows
            if (overlap.ToAppend.IsNonEmpty)
            {
                Logger.Debug(GetType(), "overlap - appending new {0} trailing rows", overlap.ToAppend.Length);

                foreach (var item in EnumerateRecords(overlap.ToAppend).AsEnumerable())
                {
                    switch (item.Item1)
                    {
                    case DataOrGroup.Data:
                        Logger.Debug(GetType(), "Appending item {0}", item.Item2);
                        AppendRowFor(item.Item2);
                        break;

                    case DataOrGroup.Group:
                        Logger.Debug(GetType(), "Appending group trailer for grp {0}", item.Item3);
                        AppendGroupTrailer(item.Item3);
                        break;

                    default: throw new Exception("unsupported DataOrGroup");
                    }
                }
            }

            var padBodyToBottom =
                newState.FirstVisibleRow == 0 ||
                newState.LastVisibleRow != (_model.Items.Length + _groups.Count * RowsPerGroupDescr - 1);

            Logger.Debug(GetType(), "Former space lead={0} trail={1}", _view.LeadSpace, _view.TrailSpace);
            _view.FirstRowIndex = newState.FirstVisibleRow;
            _view.LeadSpace     = newState.FirstVisibleRow * RowHeightPx
                                  + (padBodyToBottom ? 0 : newState.IncompleteBodyPad + newState.IncompleteLeadRowPad);
            _view.TrailSpace =
                (newState.AllRowsCount - newState.FirstVisibleRow - newState.FactVisibleRowsCount) * RowHeightPx
                + (padBodyToBottom ? newState.IncompleteBodyPad + newState.IncompleteLeadRowPad : 0);

            Logger.Debug(GetType(), "New space lead={0} trail={1} FirstVisibleRow={2}", _view.LeadSpace, _view.TrailSpace, newState.FirstVisibleRow);

            FormerState = newState;

            //_visRows.DebugPrintContents();
            //((HtmlTableBasedTableView)_view).DebugPrintContents(1);
        }