Ejemplo n.º 1
0
        /// <summary>
        /// 仮想化を実行します。
        /// </summary>
        private void Present()
        {
            _presenting = false;

            if (Layouter == null)
            {
                return;
            }

            Layouter.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));

            var elements = new HashSet <ControlBase>();

            var viewport = Viewport;

            _childRectDic.Clear();

            Layouter.CalcRectDic(_childRectDic, new Point());
            foreach (var item in _childRectDic)
            {
                if (viewport.IntersectsWith(item.Value))
                {
                    elements.Add(item.Key);
                }
            }

            // MEMO : 表示中のものを表示できる分だけのホストを作ります。
            while (_visualChildren.Count < elements.Count)
            {
                var e = new VirtualElementHost();
                AddVisualChild(e);
                _visualChildren.Add(e);
                _unusedElements.Add(e);
            }

            foreach (var c in _visualChildren)
            {
                if (c.Content != null && !elements.Contains(c.Content))
                {
                    _elements.Remove(c.Content);
                    c.Content    = null;
                    c.Visibility = Visibility.Collapsed;
                    _unusedElements.Add(c);
                }
            }

            foreach (var item in elements)
            {
                UIElement element;
                if (!_elements.TryGetValue(item, out element))
                {
                    var index = _unusedElements.Count - 1;
                    var t     = _unusedElements[index];
                    _unusedElements.RemoveAt(index);
                    t.Content    = item;
                    t.Visibility = Visibility.Visible;
                    _elements.Add(item, t);
                    t.InvalidateMeasure();
                    t.InvalidateVisual();
                }
                else
                {
                    if (item.MeasureDirty)
                    {
                        element.InvalidateMeasure();
                    }
                    if (item.ArrangeDirty)
                    {
                        element.InvalidateVisual();
                    }
                }
            }

            InvalidateMeasure();
            InvalidateVisual();
        }