/// <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(); }