private void Resizing(object sender, EventArgs e) { if (Math.Abs(_viewport.Width) > double.Epsilon) { int firstIndexCache = _firstIndex; _abstractPanel = null; MeasureOverride(_viewport); SetFirstRowViewItemIndex(_firstIndex); _firstIndex = firstIndexCache; } }
public void Resizing(object sender, EventArgs e) { if (_viewport.Width != 0) { int firstIndexCache = firstIndex; _abstractPanel = null; MeasureOverride(_viewport); SetFirstRowViewItemIndex(firstIndex); firstIndex = firstIndexCache; } }
public void Resizing(object sender, EventArgs e) { if (!(Math.Abs(_viewport.Width) > 0)) { return; } var firstIndexCache = _firstIndex; _abstractPanel = null; MeasureOverride(_viewport); SetFirstRowViewItemIndex(_firstIndex); _firstIndex = firstIndexCache; }
private void Resizing(object sender, EventArgs e) { if (Equals(_viewport.Width, 0d)) { return; } var firstIndexCache = _firstIndex; _abstractPanel = null; MeasureOverride(_viewport); SetFirstRowViewItemIndex(_firstIndex); _firstIndex = firstIndexCache; }
protected override void OnItemsChanged(object sender, ItemsChangedEventArgs args) { //Debug.WriteLine("OnItemsChanged: " + args.Action + " - " + args.ItemCount + " - " + args.ItemUICount + " - " + args.OldPosition + " - " + args.Position); _abstractPanel = null; //TODO: This is sort of copied from the VirtualizingStackPanel code. Assuming the other action cases need to be handled as well if (args.Action == NotifyCollectionChangedAction.Remove) { RemoveInternalChildRange(args.Position.Index, args.ItemUICount); } base.OnItemsChanged(sender, args); ResetScrollInfo(); }
private void OnSizeChanged(object sender, EventArgs e) { // ReSharper disable once CompareOfFloatsByEqualityOperator if (_viewport.Width != 0) { var firstIndex = _firstIndex; _abstractPanel = null; MeasureOverride(_viewport); //TODO: Isn't this wrong? SetFirstRowViewItemIndex(_firstIndex); _firstIndex = firstIndex; } }
protected override void OnItemsChanged(object sender, ItemsChangedEventArgs args) { base.OnItemsChanged(sender, args); _abstractPanel = null; ResetScrollInfo(); // ...ADD THIS... switch (args.Action) { case NotifyCollectionChangedAction.Remove: case NotifyCollectionChangedAction.Replace: RemoveInternalChildRange(args.Position.Index, args.ItemUICount); break; case NotifyCollectionChangedAction.Move: RemoveInternalChildRange(args.OldPosition.Index, args.ItemUICount); break; } }
public ItemAbstraction(WrapPanelAbstraction panel, int index) { this.panel = panel; this.index = index; }
protected override Size MeasureOverride(Size availableSize) { if (this.itemsControl == null || this.itemsControl.Items.Count == 0) { return(availableSize); } if (this.abstractPanel == null) { this.abstractPanel = new WrapPanelAbstraction(this.itemsControl.Items.Count); } this.pixelMeasuredViewport = availableSize; this.realizedChildLayout.Clear(); Size realizedFrameSize = availableSize; int itemCount = this.itemsControl.Items.Count; int firstVisibleIndex = this.GetFirstVisibleIndex(); GeneratorPosition startPos = this.generator.GeneratorPositionFromIndex(firstVisibleIndex); int childIndex = (startPos.Offset == 0) ? startPos.Index : startPos.Index + 1; int current = firstVisibleIndex; int visibleSections = 1; using (this.generator.StartAt(startPos, GeneratorDirection.Forward, true)) { bool stop = false; bool isHorizontal = Orientation == Orientation.Horizontal; double currentX = 0; double currentY = 0; double maxItemSize = 0; int currentSection = this.GetFirstVisibleSection(); while (current < itemCount) { bool newlyRealized; // Get or create the child UIElement child = this.generator.GenerateNext(out newlyRealized) as UIElement; if (newlyRealized) { // Figure out if we need to insert the child at the end or somewhere in the middle if (childIndex >= this.children.Count) { this.AddInternalChild(child); } else { this.InsertInternalChild(childIndex, child); } this.generator.PrepareItemContainer(child); child.Measure(this.ChildSlotSize); } else { // The child has already been created, let's be sure it's in the right spot Debug.Assert(child == this.children[childIndex], "Wrong child was generated"); } this.childSize = child.DesiredSize; Rect childRect = new Rect(new Point(currentX, currentY), this.childSize); if (isHorizontal) { maxItemSize = Math.Max(maxItemSize, childRect.Height); // wrap to a new line if (childRect.Right > realizedFrameSize.Width) { currentY = currentY + maxItemSize; currentX = 0; maxItemSize = childRect.Height; childRect.X = currentX; childRect.Y = currentY; currentSection++; visibleSections++; } if (currentY > realizedFrameSize.Height) { stop = true; } currentX = childRect.Right; } else { maxItemSize = Math.Max(maxItemSize, childRect.Width); // wrap to a new column if (childRect.Bottom > realizedFrameSize.Height) { currentX = currentX + maxItemSize; currentY = 0; maxItemSize = childRect.Width; childRect.X = currentX; childRect.Y = currentY; currentSection++; visibleSections++; } if (currentX > realizedFrameSize.Width) { stop = true; } currentY = childRect.Bottom; } this.realizedChildLayout.Add(child, childRect); this.abstractPanel.SetItemSection(current, currentSection); if (stop) { break; } current++; childIndex++; } } this.CleanUpItems(firstVisibleIndex, current - 1); this.ComputeExtentAndViewport(availableSize, visibleSections); if (double.IsPositiveInfinity(availableSize.Height)) { availableSize.Height = 0D; } if (double.IsPositiveInfinity(availableSize.Width)) { availableSize.Width = 0D; } return(availableSize); }
protected override void OnItemsChanged(object sender, ItemsChangedEventArgs args) { base.OnItemsChanged(sender, args); this.abstractPanel = null; this.ResetScrollInfo(); }
public ItemAbstraction(WrapPanelAbstraction panel, int index) { _panel = panel; _index = index; }
protected override Size MeasureOverride(Size availableSize) { if (_itemsControl == null || _itemsControl.Items.Count == 0) { return(availableSize); } if (_abstractPanel == null) { _abstractPanel = new WrapPanelAbstraction(_itemsControl.Items.Count); } _pixelMeasuredViewport = availableSize; _realizedChildLayout.Clear(); var realizedFrameSize = availableSize; var itemCount = _itemsControl.Items.Count; var firstVisibleIndex = GetFirstVisibleIndex(); var startPos = _generator.GeneratorPositionFromIndex(firstVisibleIndex); var childIndex = (startPos.Offset == 0) ? startPos.Index : startPos.Index + 1; var childSlotSize = ChildSlotSize; var current = firstVisibleIndex; var visibleSections = 1; using (_generator.StartAt(startPos, GeneratorDirection.Forward, true)) { var stop = false; var isHorizontal = Orientation == Orientation.Horizontal; double currentX = 0; double currentY = 0; double maxItemSize = 0; var currentSection = GetFirstVisibleSection(); while (current < itemCount) { bool newlyRealized; // Get or create the child var child = _generator.GenerateNext(out newlyRealized) as UIElement; if (child == null) { throw new InvalidOperationException("'child' cannot be null"); } if (newlyRealized) { // Figure out if we need to insert the child at the end or somewhere in the middle if (childIndex >= _children.Count) { AddInternalChild(child); } else { base.InsertInternalChild(childIndex, child); } _generator.PrepareItemContainer(child); child.Measure(childSlotSize); } else { if ((!childSlotSize.Height.Equals(double.PositiveInfinity) && !child.DesiredSize.Height.Equals(childSlotSize.Height)) || (!childSlotSize.Width.Equals(double.PositiveInfinity) && !child.DesiredSize.Width.Equals(childSlotSize.Width))) { // Re-measure if the ChildSlotSize has changed child.Measure(childSlotSize); } // ReSharper disable once PossibleUnintendedReferenceComparison // The child has already been created, let's be sure it's in the right spot Debug.Assert(child == _children[childIndex], "Wrong child was generated"); } _childSize = child.DesiredSize; var childRect = new Rect(new Point(currentX, currentY), _childSize); if (isHorizontal) { maxItemSize = Math.Max(maxItemSize, childRect.Height); if (childRect.Right > realizedFrameSize.Width) //wrap to a new line { currentY = currentY + maxItemSize; currentX = 0; maxItemSize = childRect.Height; childRect.X = currentX; childRect.Y = currentY; currentSection++; visibleSections++; } if (currentY > realizedFrameSize.Height) { stop = true; } currentX = childRect.Right; } else { maxItemSize = Math.Max(maxItemSize, childRect.Width); if (childRect.Bottom > realizedFrameSize.Height) //wrap to a new column { currentX = currentX + maxItemSize; currentY = 0; maxItemSize = childRect.Width; childRect.X = currentX; childRect.Y = currentY; currentSection++; visibleSections++; } if (currentX > realizedFrameSize.Width) { stop = true; } currentY = childRect.Bottom; } _realizedChildLayout.Add(child, childRect); _abstractPanel.SetItemSection(current, currentSection); if (stop) { break; } current++; childIndex++; } } CleanUpItems(firstVisibleIndex, current - 1); ComputeExtentAndViewport(availableSize, visibleSections); return(availableSize); }
protected override Size MeasureOverride(Size availableSize) { if (_itemsControl == null || _itemsControl.Items.Count == 0) { return(availableSize); } if (_abstractPanel == null) { _abstractPanel = new WrapPanelAbstraction(_itemsControl.Items.Count); } _pixelMeasuredViewport = availableSize; _realizedChildLayout.Clear(); Size realizedFrameSize = availableSize; int itemCount = _itemsControl.Items.Count; int firstVisibleIndex = GetFirstVisibleIndex(); GeneratorPosition startPos = _generator.GeneratorPositionFromIndex(firstVisibleIndex); int childIndex = (startPos.Offset == 0) ? startPos.Index : startPos.Index + 1; int current = firstVisibleIndex; int visibleSections = 1; int itemsPerRow = (int)Math.Floor(realizedFrameSize.Width / ItemWidth); int visiblePerScreen = (!double.IsNaN(ItemHeight) && ItemHeight > 0 ? (int)Math.Ceiling((realizedFrameSize.Height - 1) / ItemHeight + 1) : 0); using (_generator.StartAt(startPos, GeneratorDirection.Forward, true)) { bool stop = false; bool isHorizontal = Orientation == Orientation.Horizontal; double currentX = 0; double currentY = 0; double maxItemSize = 0; int currentSection = GetFirstVisibleSection(); currentY -= ChildSlotSize.Height * (VerticalOffset - currentSection); while (current < itemCount) { bool newlyRealized; // Get or create the child UIElement child = _generator.GenerateNext(out newlyRealized) as UIElement; if (newlyRealized) { if (child is FrameworkElement) { ((FrameworkElement)child).HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch; ((FrameworkElement)child).VerticalAlignment = System.Windows.VerticalAlignment.Stretch; } // Figure out if we need to insert the child at the end or somewhere in the middle if (childIndex >= _children.Count) { base.AddInternalChild(child); } else { base.InsertInternalChild(childIndex, child); } _generator.PrepareItemContainer(child); child.Measure(ChildSlotSize); } else { // The child has already been created, let's be sure it's in the right spot Debug.Assert(child == _children[childIndex], "Wrong child was generated"); } childSize = child.DesiredSize; Rect childRect = new Rect(new Point(currentX, currentY), childSize); if (isHorizontal) { maxItemSize = Math.Max(maxItemSize, childRect.Height); if (childRect.Right > realizedFrameSize.Width) //wrap to a new line { currentY = currentY + maxItemSize; currentX = 0; maxItemSize = childRect.Height; childRect.X = currentX; childRect.Y = currentY; currentSection++; visibleSections++; } if (currentY > realizedFrameSize.Height) { stop = true; } currentX = childRect.Right; } else { maxItemSize = Math.Max(maxItemSize, childRect.Width); if (childRect.Bottom > realizedFrameSize.Height) //wrap to a new column { currentX = currentX + maxItemSize; currentY = 0; maxItemSize = childRect.Width; childRect.X = currentX; childRect.Y = currentY; currentSection++; visibleSections++; } if (currentX > realizedFrameSize.Width) { stop = true; } currentY = childRect.Bottom; } _realizedChildLayout.Add(child, childRect); _abstractPanel.SetItemSection(current, currentSection); //if (stop) if (current >= firstVisibleIndex + visiblePerScreen * itemsPerRow) { break; } current++; childIndex++; } } CleanUpItems(firstVisibleIndex, current - 1); if (visiblePerScreen == 0) { visiblePerScreen = visibleSections; } ComputeExtentAndViewport(availableSize, visiblePerScreen); return(availableSize); }
protected override Size MeasureOverride(Size availableSize) { // Optimized for fixed sizes! if (_itemsControl == null || _itemsControl.Items.Count == 0) { return(availableSize); } if (_abstractPanel == null) { _abstractPanel = new WrapPanelAbstraction(_itemsControl.Items.Count); } _pixelMeasuredViewport = availableSize; _realizedChildLayout.Clear(); var realizedFrameSize = availableSize; int itemCount = _itemsControl.Items.Count; int firstVisibleIndex = GetFirstVisibleIndex(); var startPos = _generator.GeneratorPositionFromIndex(firstVisibleIndex); int childIndex = (startPos.Offset == 0) ? startPos.Index : startPos.Index + 1; int current = firstVisibleIndex; int visibleSections = 1; using (_generator.StartAt(startPos, GeneratorDirection.Forward, true)) { bool stop = false; bool isHorizontal = Orientation == Orientation.Horizontal; double currentX = 0; double currentY = 0; int currentSection = GetFirstVisibleSection(); while (current < itemCount) { // Get or create the child var child = _generator.GenerateNext(out bool newlyRealized) as UIElement; if (newlyRealized) { // Figure out if we need to insert the child at the end or somewhere in the middle if (childIndex >= _children.Count) { base.AddInternalChild(child); } else { base.InsertInternalChild(childIndex, child); } _generator.PrepareItemContainer(child); child.Measure(ChildSlotSize); } else { // The child has already been created, let's be sure it's in the right spot Debug.Assert(child == _children[childIndex], "Wrong child was generated"); } var childRect = new Rect(currentX, currentY, ItemWidth, ItemHeight); if (isHorizontal) { if (childRect.Right > realizedFrameSize.Width) //wrap to a new line { currentY = currentY + ItemHeight; currentX = 0; childRect.X = currentX; childRect.Y = currentY; currentSection++; visibleSections++; } if (currentY > realizedFrameSize.Height) { stop = true; } currentX = childRect.Right; } else { if (childRect.Bottom > realizedFrameSize.Height) //wrap to a new column { currentX = currentX + ItemWidth; currentY = 0; childRect.X = currentX; childRect.Y = currentY; currentSection++; visibleSections++; } if (currentX > realizedFrameSize.Width) { stop = true; } currentY = childRect.Bottom; } _realizedChildLayout.Add(child, childRect); _abstractPanel.SetItemSection(current, currentSection); if (stop) { break; } current++; childIndex++; } } CleanUpItems(firstVisibleIndex, current - 1); ComputeExtentAndViewport(availableSize, visibleSections); return(availableSize); }
/// <summary> /// Measures the child elements of a WrapPanel in anticipation of arranging them during the ArrangeOverride pass.</summary> /// <param name="availableSize">The size available to child elements of the wrap panel</param> /// <returns>The size required by the WrapPanel and its child elements.</returns> protected override Size MeasureOverride(Size availableSize) { Debug.WriteLine($"From Measure Override. Height: {availableSize.Height} / Width: {availableSize.Width}"); if (ScrollOwner == null || !ScrollOwner.CanContentScroll) { availableSize = new Size(ActualWidth, ActualHeight); } Debug.WriteLine($"From Control. Height: {ActualHeight} / Width: {ActualWidth}"); if (availableSize.Height == Double.PositiveInfinity) { availableSize = new Size(availableSize.Width, ActualHeight); } if (availableSize.Width == Double.PositiveInfinity) { availableSize = new Size(ActualWidth, availableSize.Height); } if (m_itemsControl == null || m_itemsControl.Items.Count == 0) { Debug.WriteLine("NO ITEMS!!!!!!!!!!!"); ComputeExtentAndViewport(availableSize); return(availableSize); } if (m_abstractPanel == null) { m_abstractPanel = new WrapPanelAbstraction(m_itemsControl.Items.Count); } m_pixelMeasuredViewport = availableSize; m_realizedChildLayout.Clear(); Size realizedFrameSize = availableSize; int itemCount = m_itemsControl.Items.Count; int firstVisibleIndex = GetFirstVisibleIndex(); Debug.WriteLine("First visible index from Measure: " + firstVisibleIndex); var startPos = m_generator.GeneratorPositionFromIndex(firstVisibleIndex); int childIndex = (startPos.Offset == 0) ? startPos.Index : startPos.Index + 1; int current = firstVisibleIndex; int visibleSections = 1; bool changeColumn = false; using (m_generator.StartAt(startPos, GeneratorDirection.Forward, true)) { bool stop = false; bool isHorizontal = Orientation == Orientation.Horizontal; double currentX = 0; double currentY = 0; double maxItemSize = 0; Size slotSize = ChildSlotSize; int currentSection = GetFirstVisibleSection(); if (currentSection < 0) { currentSection = 0; } var maximumRectanglesForColumn = new Dictionary <UIElement, Rect>(); var maximumRectanglesTotal = new Dictionary <UIElement, Rect>(); while (current < itemCount) { // Get or create the child if (!(m_generator.GenerateNext(out bool newlyRealized) is UIElement child)) { break; } if (child is ListViewItem listchild) { listchild.Selected -= ListViewItemSelected; } if (newlyRealized) { // Figure out if we need to insert the child at the end or somewhere in the middle if (childIndex >= m_children.Count) { base.AddInternalChild(child); } else { base.InsertInternalChild(childIndex, child); } m_generator.PrepareItemContainer(child); child.Measure(slotSize); } else { // The child has already been created, let's be sure it's in the right spot Debug.Assert(child == m_children[childIndex], "Wrong child was generated"); child.Measure(slotSize); } m_childSize = child.DesiredSize; Rect childRect = new Rect(new Point(currentX, currentY), m_childSize); if (isHorizontal) { maxItemSize = Math.Max(maxItemSize, childRect.Height); if (childRect.Right > realizedFrameSize.Width) //wrap to a new line { currentY = currentY + maxItemSize; currentX = 0; maxItemSize = childRect.Height; childRect.X = currentX; childRect.Y = currentY; currentSection++; visibleSections++; } if (currentY > realizedFrameSize.Height) { stop = true; } currentX = childRect.Right; } else { changeColumn = childRect.Bottom > realizedFrameSize.Height; if (changeColumn) //maximize the size { foreach (var item in maximumRectanglesForColumn) { var c = item.Value; c.Width = maxItemSize; maximumRectanglesTotal.Add(item.Key, c); } if (m_abstractPanel.AverageItemsPerSection == itemCount || m_abstractPanel.AverageItemsPerSection != maximumRectanglesForColumn.Count) { m_abstractPanel.AverageItemsPerSection = maximumRectanglesForColumn.Count; } maximumRectanglesForColumn.Clear(); } maxItemSize = Math.Max(maxItemSize, childRect.Width); if (changeColumn) //wrap to a new column { currentX = currentX + maxItemSize; currentY = 0; maxItemSize = 0; childRect.X = currentX; childRect.Y = currentY; if (currentX > realizedFrameSize.Width) { Debug.WriteLine("ADDING CHILDREN STOPPED AT X: " + currentX + "/ Current: " + current); stop = true; } else { visibleSections++; currentSection++; } } maximumRectanglesForColumn.Add(child, childRect); currentY = childRect.Bottom; } if (stop) { break; } current++; childIndex++; } if (maximumRectanglesForColumn.Count == 1 && maxItemSize == 0) { maxItemSize = maximumRectanglesForColumn.First().Value.Width; } foreach (var item in maximumRectanglesForColumn) { var c = item.Value; c.Width = maxItemSize; maximumRectanglesTotal.Add(item.Key, c); } m_lastIndexCompletelyVisible = itemCount == current && (currentX + maxItemSize < realizedFrameSize.Width); Debug.WriteLineIf(m_lastIndexCompletelyVisible, "The last index is completely rendered."); maximumRectanglesForColumn.Clear(); m_realizedChildLayout = maximumRectanglesTotal; } //compute ComputeExtentAndViewport(availableSize, visibleSections); CleanUpItems(firstVisibleIndex, current - 1); return(availableSize); }