/// <inheritdoc /> protected override void OnDropDownOpened(EventArgs e) { base.OnDropDownOpened(e); Mouse.Capture(this, CaptureMode.SubTree); if (this.SelectedItem != null) { Keyboard.Focus(this.ItemContainerGenerator.ContainerOrContainerContentFromItem <IInputElement>(this.SelectedItem)); } this.focusedElement = Keyboard.FocusedElement; if (this.focusedElement != null) { this.focusedElement.LostKeyboardFocus += this.OnFocusedElementLostKeyboardFocus; } this.canSizeY = true; this.scrollViewer.Width = double.NaN; this.scrollViewer.Height = double.NaN; var popupChild = this.DropDownPopup.Child as FrameworkElement; var initialHeight = Math.Min(RibbonControl.GetControlWorkArea(this).Height * 2 / 3, this.MaxDropDownHeight); if (double.IsNaN(this.DropDownHeight) == false) { initialHeight = Math.Min(this.DropDownHeight, this.MaxDropDownHeight); } if (this.scrollViewer.DesiredSize.Height > initialHeight) { this.scrollViewer.Height = initialHeight; } popupChild?.UpdateLayout(); }
/// <summary> /// Gets control which represents shortcut item. /// This item MUST be synchronized with the original /// and send command to original one control. /// </summary> /// <returns>Control which represents shortcut item</returns> public virtual FrameworkElement CreateQuickAccessItem() { var button = new DropDownButton { Size = RibbonControlSize.Small }; BindQuickAccessItem(button); RibbonControl.Bind(this, button, "DisplayMemberPath", DisplayMemberPathProperty, BindingMode.OneWay); RibbonControl.Bind(this, button, "GroupStyleSelector", GroupStyleSelectorProperty, BindingMode.OneWay); RibbonControl.Bind(this, button, "ItemContainerStyle", ItemContainerStyleProperty, BindingMode.OneWay); RibbonControl.Bind(this, button, "ItemsPanel", ItemsPanelProperty, BindingMode.OneWay); RibbonControl.Bind(this, button, "ItemStringFormat", ItemStringFormatProperty, BindingMode.OneWay); RibbonControl.Bind(this, button, "ItemTemplate", ItemTemplateProperty, BindingMode.OneWay); RibbonControl.Bind(this, button, "MaxDropDownHeight", MaxDropDownHeightProperty, BindingMode.OneWay); BindQuickAccessItemDropDownEvents(button); button.DropDownOpened += OnQuickAccessOpened; return button; }
/// <inheritdoc /> public virtual FrameworkElement CreateQuickAccessItem() { var button = new DropDownButton { Size = RibbonControlSize.Small }; this.BindQuickAccessItem(button); RibbonControl.Bind(this, button, nameof(this.DisplayMemberPath), DisplayMemberPathProperty, BindingMode.OneWay); RibbonControl.Bind(this, button, nameof(this.GroupStyleSelector), GroupStyleSelectorProperty, BindingMode.OneWay); RibbonControl.Bind(this, button, nameof(this.ItemContainerStyle), ItemContainerStyleProperty, BindingMode.OneWay); RibbonControl.Bind(this, button, nameof(this.ItemsPanel), ItemsPanelProperty, BindingMode.OneWay); RibbonControl.Bind(this, button, nameof(this.ItemStringFormat), ItemStringFormatProperty, BindingMode.OneWay); RibbonControl.Bind(this, button, nameof(this.ItemTemplate), ItemTemplateProperty, BindingMode.OneWay); RibbonControl.Bind(this, button, nameof(this.MaxDropDownHeight), MaxDropDownHeightProperty, BindingMode.OneWay); this.BindQuickAccessItemDropDownEvents(button); button.DropDownOpened += this.OnQuickAccessOpened; return(button); }
// Creates menu private void RecreateMenu() { contextMenu.Items.Clear(); // Adding header separator contextMenu.Items.Add(new GroupSeparatorMenuItem()); RibbonControl.Bind(Ribbon.Localization, contextMenu.Items[0] as FrameworkElement, "CustomizeStatusBar", MenuItem.HeaderProperty, BindingMode.OneWay); for (int i = 0; i < Items.Count; i++) { StatusBarItem item = Items[i] as StatusBarItem; if (item != null) { item.Checked += OnItemChecked; item.Unchecked += OnItemUnchecked; contextMenu.Items.Add(new StatusBarMenuItem(item)); } else { contextMenu.Items.Add(new Separator()); } } UpdateSeparartorsVisibility(); }
/// <summary> /// Handles Command changed /// </summary> /// <param name="d"></param> /// <param name="e"></param> private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { RibbonControl control = d as RibbonControl; EventHandler handler = control.OnCommandCanExecuteChanged; if (e.OldValue != null) { (e.OldValue as ICommand).CanExecuteChanged -= handler; } if (e.NewValue != null) { handler = new EventHandler(control.OnCommandCanExecuteChanged); control.canExecuteChangedHandler = handler; (e.NewValue as ICommand).CanExecuteChanged += handler; RoutedUICommand cmd = e.NewValue as RoutedUICommand; if ((cmd != null) && (control.Header == null)) { control.Header = cmd.Text; } } control.UpdateCanExecute(); }
/// <summary> /// Gets control which represents shortcut item. /// This item MUST be syncronized with the original /// and send command to original one control. /// </summary> /// <returns>Control which represents shortcut item</returns> public FrameworkElement CreateQuickAccessItem() { RibbonGroupBox groupBox = new RibbonGroupBox(); groupBox.DropDownOpened += OnQuickAccessOpened; groupBox.DropDownClosed += OnQuickAccessClosed; groupBox.State = RibbonGroupBoxState.QuickAccess; //RibbonControl.BindQuickAccessItem(this, groupBox); //if (QuickAccessElementStyle != null) RibbonControl.Bind(this, groupBox, "QuickAccessElementStyle", StyleProperty, BindingMode.OneWay); //RibbonControl.Bind(this, groupBox, "Icon", RibbonControl.IconProperty, BindingMode.OneWay); if (Icon != null) { Visual iconVisual = Icon as Visual; if (iconVisual != null) { Rectangle rect = new Rectangle(); rect.Width = 16; rect.Height = 16; rect.Fill = new VisualBrush(iconVisual); groupBox.Icon = rect; } else { RibbonControl.Bind(this, groupBox, "Icon", RibbonControl.IconProperty, BindingMode.OneWay); } } if (Header != null) { RibbonControl.Bind(this, groupBox, "Header", RibbonControl.HeaderProperty, BindingMode.OneWay); } return(groupBox); }
/// <summary> /// Implements custom placement for ribbon popup /// </summary> /// <param name="popupsize"></param> /// <param name="targetsize"></param> /// <param name="offset"></param> /// <returns></returns> CustomPopupPlacement[] CustomPopupPlacementMethod(Size popupsize, Size targetsize, Point offset) { if (popup != null) { Rect monitorRect = RibbonControl.GetControlMonitor(this); Point pos = PointToScreen(new Point()); if (ShowPopupOnTop) { return(new CustomPopupPlacement[] { new CustomPopupPlacement(new Point(0, -dropDownBorder.ActualHeight), PopupPrimaryAxis.Horizontal), }); } else { return(new CustomPopupPlacement[] { new CustomPopupPlacement(new Point(0, ActualHeight), PopupPrimaryAxis.Horizontal), }); } } return(null); }
/// <summary> /// Reports when a combo box's popup opens. /// </summary> /// <param name="e">The event data for the <see cref="E:System.Windows.Controls.ComboBox.DropDownOpened" /> event.</param> protected override void OnDropDownOpened(EventArgs e) { base.OnDropDownOpened(e); Mouse.Capture(this, CaptureMode.SubTree); if (this.SelectedItem != null) { Keyboard.Focus(this.ItemContainerGenerator.ContainerFromItem(this.SelectedItem) as IInputElement); } this.focusedElement = Keyboard.FocusedElement; if (this.focusedElement != null) { this.focusedElement.LostKeyboardFocus += this.OnFocusedElementLostKeyboardFocus; } this.canSizeY = true; this.galleryPanel.Width = double.NaN; this.scrollViewer.Height = double.NaN; var popupChild = this.DropDownPopup.Child as FrameworkElement; var heightDelta = popupChild.DesiredSize.Height - this.scrollViewer.DesiredSize.Height; var initialHeight = Math.Min(RibbonControl.GetControlWorkArea(this).Height * 2 / 3, this.MaxDropDownHeight); if (double.IsNaN(this.DropDownHeight) == false) { initialHeight = Math.Min(this.DropDownHeight, this.MaxDropDownHeight); } if (this.scrollViewer.DesiredSize.Height > initialHeight) { this.scrollViewer.Height = initialHeight; } else { initialHeight = this.scrollViewer.DesiredSize.Height; } var monitor = RibbonControl.GetControlMonitor(this); var delta = monitor.Bottom - this.PointToScreen(new Point()).Y - this.ActualHeight - initialHeight - heightDelta; if (delta >= 0) { this.ShowPopupOnTop = false; } else { var deltaTop = this.PointToScreen(new Point()).Y - initialHeight - heightDelta - monitor.Top; if (deltaTop > delta) { this.ShowPopupOnTop = true; } else { this.ShowPopupOnTop = false; } if (deltaTop < 0) { delta = Math.Max(Math.Abs(delta), Math.Abs(deltaTop)); if (delta > this.galleryPanel.GetItemSize().Height) { this.scrollViewer.Height = delta; } else { this.canSizeY = false; this.scrollViewer.Height = this.galleryPanel.GetItemSize().Height; } } } popupChild.UpdateLayout(); }
private void Refresh() { // Clear currently used group containers // and supply with new generated ones foreach (var galleryGroupContainer in this.galleryGroupContainers) { BindingOperations.ClearAllBindings(galleryGroupContainer); this.visualCollection.Remove(galleryGroupContainer); } this.galleryGroupContainers.Clear(); // Gets filters var filter = this.Filter?.Split(','); var dictionary = new Dictionary <string, GalleryGroupContainer>(); foreach (UIElement item in this.InternalChildren) { if (item == null) { continue; } // Resolve group name string propertyValue = null; if (this.GroupByAdvanced != null) { propertyValue = this.ItemContainerGenerator == null ? this.GroupByAdvanced(item) : this.GroupByAdvanced(this.ItemContainerGenerator.ItemFromContainerOrContainerContent(item)); } else if (string.IsNullOrEmpty(this.GroupBy) == false) { propertyValue = this.ItemContainerGenerator == null ? this.GetPropertyValueAsString(item) : this.GetPropertyValueAsString(this.ItemContainerGenerator.ItemFromContainerOrContainerContent(item)); } if (propertyValue == null) { propertyValue = Undefined; } // Make invisible if it is not in filter (or is not grouped) if (this.IsGrouped == false || (filter != null && filter.Contains(propertyValue) == false)) { item.Measure(new Size(0, 0)); item.Arrange(new Rect(0, 0, 0, 0)); } // Skip if it is not in filter if (filter != null && filter.Contains(propertyValue) == false) { continue; } // To put all items in one group in case of IsGrouped = False if (this.IsGrouped == false) { propertyValue = Undefined; } if (dictionary.ContainsKey(propertyValue) == false) { var galleryGroupContainer = new GalleryGroupContainer { Header = propertyValue }; RibbonControl.Bind(this, galleryGroupContainer, nameof(this.Orientation), GalleryGroupContainer.OrientationProperty, BindingMode.OneWay); RibbonControl.Bind(this, galleryGroupContainer, nameof(this.ItemWidth), GalleryGroupContainer.ItemWidthProperty, BindingMode.OneWay); RibbonControl.Bind(this, galleryGroupContainer, nameof(this.ItemHeight), GalleryGroupContainer.ItemHeightProperty, BindingMode.OneWay); RibbonControl.Bind(this, galleryGroupContainer, nameof(this.MaxItemsInRow), GalleryGroupContainer.MaxItemsInRowProperty, BindingMode.OneWay); RibbonControl.Bind(this, galleryGroupContainer, nameof(this.MinItemsInRow), GalleryGroupContainer.MinItemsInRowProperty, BindingMode.OneWay); dictionary.Add(propertyValue, galleryGroupContainer); this.galleryGroupContainers.Add(galleryGroupContainer); this.visualCollection.Add(galleryGroupContainer); } dictionary[propertyValue].Items.Add(new GalleryItemPlaceholder(item)); } if ((this.IsGrouped == false || (this.GroupBy == null && this.GroupByAdvanced == null)) && this.galleryGroupContainers.Count != 0) { // Make it without headers if there is only one group or if we are not supposed to group this.galleryGroupContainers[0].IsHeadered = false; } this.UpdateMinAndMaxWidth(); this.InvalidateMeasure(); }
void Refresh() { // Clear currently used group containers // and supply with new generated ones foreach (GalleryGroupContainer galleryGroupContainer in galleryGroupContainers) { BindingOperations.ClearAllBindings(galleryGroupContainer); //RemoveVisualChild(galleryGroupContainer); visualCollection.Remove(galleryGroupContainer); } galleryGroupContainers.Clear(); // Gets filters string[] filter = Filter == null ? null : Filter.Split(','); Dictionary <string, GalleryGroupContainer> dictionary = new Dictionary <string, GalleryGroupContainer>(); foreach (UIElement item in InternalChildren) { if (item == null) { continue; } // Resolve group name string propertyValue; if (GroupByAdvanced == null) { propertyValue = (ItemContainerGenerator == null) ? GetPropertyValueAsString(item) : GetPropertyValueAsString(ItemContainerGenerator.ItemFromContainer(item)); } else { propertyValue = (ItemContainerGenerator == null) ? GroupByAdvanced(item) : GroupByAdvanced(ItemContainerGenerator.ItemFromContainer(item)); } if (propertyValue == null) { propertyValue = "Undefined"; } // Make invisible if it is not in filter (or is not grouped) if ((!IsGrouped) || (filter != null && !filter.Contains(propertyValue))) { item.Measure(new Size(0, 0)); item.Arrange(new Rect(0, 0, 0, 0)); } // Skip if it is not in filter if (filter != null && !filter.Contains(propertyValue)) { continue; } // To put all items in one group in case of IsGrouped = False if (!IsGrouped) { propertyValue = "Undefined"; } if (!dictionary.ContainsKey(propertyValue)) { GalleryGroupContainer galleryGroupContainer = new GalleryGroupContainer(); galleryGroupContainer.Header = propertyValue; RibbonControl.Bind(this, galleryGroupContainer, "GroupStyle", GroupStyleProperty, BindingMode.OneWay); RibbonControl.Bind(this, galleryGroupContainer, "Orientation", GalleryGroupContainer.OrientationProperty, BindingMode.OneWay); RibbonControl.Bind(this, galleryGroupContainer, "ItemWidth", GalleryGroupContainer.ItemWidthProperty, BindingMode.OneWay); RibbonControl.Bind(this, galleryGroupContainer, "ItemHeight", GalleryGroupContainer.ItemHeightProperty, BindingMode.OneWay); RibbonControl.Bind(this, galleryGroupContainer, "MaxItemsInRow", GalleryGroupContainer.MaxItemsInRowProperty, BindingMode.OneWay); RibbonControl.Bind(this, galleryGroupContainer, "MinItemsInRow", GalleryGroupContainer.MinItemsInRowProperty, BindingMode.OneWay); dictionary.Add(propertyValue, galleryGroupContainer); galleryGroupContainers.Add(galleryGroupContainer); visualCollection.Add(galleryGroupContainer); } dictionary[propertyValue].Items.Add(new GalleryItemPlaceholder(item)); } if (((!IsGrouped) || (GroupBy == null && GroupByAdvanced == null)) && galleryGroupContainers.Count != 0) { // Make it without headers galleryGroupContainers[0].IsHeadered = false; } InvalidateMeasure(); }
/// <summary> /// Reports when a combo box's popup opens. /// </summary> /// <param name="e">The event data for the <see cref="E:System.Windows.Controls.ComboBox.DropDownOpened"/> event.</param> protected override void OnDropDownOpened(EventArgs e) { base.OnDropDownOpened(e); Mouse.Capture(this, CaptureMode.SubTree); if (SelectedItem != null) { Keyboard.Focus(ItemContainerGenerator.ContainerFromItem(SelectedItem) as IInputElement); } focusedElement = Keyboard.FocusedElement; focusedElement.LostKeyboardFocus += OnFocusedElementLostKeyboardFocus; canSizeX = true; canSizeY = true; galleryPanel.Width = double.NaN; scrollViewer.Height = double.NaN; FrameworkElement popupChild = popup.Child as FrameworkElement; scrollViewer.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); popupChild.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); popup.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); double heightDelta = popupChild.DesiredSize.Height - scrollViewer.DesiredSize.Height; double initialHeight = Math.Min(RibbonControl.GetControlWorkArea(this).Height * 2 / 3, MaxDropDownHeight); if (!double.IsNaN(DropDownHeight)) { initialHeight = Math.Min(DropDownHeight, MaxDropDownHeight); } if (scrollViewer.DesiredSize.Height > initialHeight) { scrollViewer.Height = initialHeight; } else { initialHeight = scrollViewer.DesiredSize.Height; } Rect monitor = RibbonControl.GetControlMonitor(this); double delta = monitor.Bottom - this.PointToScreen(new Point()).Y - ActualHeight - initialHeight - heightDelta; if (delta >= 0) { ShowPopupOnTop = false; } else { double deltaTop = this.PointToScreen(new Point()).Y - initialHeight - heightDelta - monitor.Top; if (deltaTop > delta) { ShowPopupOnTop = true; } else { ShowPopupOnTop = false; } if (deltaTop < 0) { delta = Math.Max(Math.Abs(delta), Math.Abs(deltaTop)); if (delta > galleryPanel.GetItemSize().Height) { scrollViewer.Height = delta; } else { canSizeY = false; scrollViewer.Height = galleryPanel.GetItemSize().Height; } } } popupChild.UpdateLayout(); }
private void Refresh() { if (this.needsRefresh == false) { return; } this.needsRefresh = false; if (this.itemContainerGeneratorAction == null) { this.itemContainerGeneratorAction = new ItemContainerGeneratorAction((ItemContainerGenerator)this.ItemContainerGenerator, this.Refresh); } // Clear currently used group containers // and supply with new generated ones foreach (var galleryGroupContainer in this.galleryGroupContainers) { BindingOperations.ClearAllBindings(galleryGroupContainer); this.visualCollection.Remove(galleryGroupContainer); } this.galleryGroupContainers.Clear(); // Gets filters var filter = this.Filter?.Split(','); var dictionary = new Dictionary <string, GalleryGroupContainer>(); foreach (UIElement item in this.InternalChildren) { if (item == null) { continue; } // Resolve group name string propertyValue = null; if (this.GroupByAdvanced == null) { propertyValue = this.ItemContainerGenerator == null ? this.GetPropertyValueAsString(item) : this.GetPropertyValueAsString(this.ItemContainerGenerator.GetItemContainerGeneratorForPanel(this).ItemFromContainer(item)); } else { propertyValue = this.ItemContainerGenerator == null ? this.GroupByAdvanced(item) : this.GroupByAdvanced(this.ItemContainerGenerator.GetItemContainerGeneratorForPanel(this).ItemFromContainer(item)); } if (propertyValue == null) { propertyValue = "Undefined"; } // Make invisible if it is not in filter if (this.IsGrouped && filter != null && filter.Contains(propertyValue) == false) { item.Visibility = Visibility.Collapsed; continue; } // Make all not filtered items visible item.Visibility = Visibility.Visible; // To put all items in one group in case of IsGrouped = False if (this.IsGrouped == false) { propertyValue = "Undefined"; } if (dictionary.ContainsKey(propertyValue) == false) { var galleryGroupContainer = new GalleryGroupContainer { Header = propertyValue }; RibbonControl.Bind(this, galleryGroupContainer, "GroupStyle", GroupStyleProperty, BindingMode.OneWay); RibbonControl.Bind(this, galleryGroupContainer, "Orientation", GalleryGroupContainer.OrientationProperty, BindingMode.OneWay); RibbonControl.Bind(this, galleryGroupContainer, "ItemWidth", GalleryGroupContainer.ItemWidthProperty, BindingMode.OneWay); RibbonControl.Bind(this, galleryGroupContainer, "ItemHeight", GalleryGroupContainer.ItemHeightProperty, BindingMode.OneWay); RibbonControl.Bind(this, galleryGroupContainer, "MaxItemsInRow", GalleryGroupContainer.MaxItemsInRowProperty, BindingMode.OneWay); RibbonControl.Bind(this, galleryGroupContainer, "MinItemsInRow", GalleryGroupContainer.MinItemsInRowProperty, BindingMode.OneWay); dictionary.Add(propertyValue, galleryGroupContainer); this.galleryGroupContainers.Add(galleryGroupContainer); this.visualCollection.Add(galleryGroupContainer); } dictionary[propertyValue].Items.Add(new GalleryItemPlaceholder(item)); } if ((this.IsGrouped == false || (this.GroupBy == null && this.GroupByAdvanced == null)) && this.galleryGroupContainers.Count != 0) { // Make it without headers this.galleryGroupContainers[0].IsHeadered = false; } this.InvalidateMeasure(); }
/// <summary> /// Layout logic for the given layout definition /// </summary> /// <param name="layoutDefinition">Current layout definition</param> /// <param name="availableSize">Available or final size</param> /// <param name="measure">Pass true if measure required; pass false if arrange required</param> /// <param name="addchildren">Determines whether we have to add children to the logical and visual tree</param> /// <returns>Final size</returns> Size CustomLayout(RibbonToolBarLayoutDefinition layoutDefinition, Size availableSize, bool measure, bool addchildren) { bool arrange = !measure; double availableHeight = Double.IsPositiveInfinity(availableSize.Height) ? 0 : availableSize.Height; // Clear separator cahce if (addchildren) { separatorCache.Clear(); } // Get the first control and measure, its height accepts as row height double rowHeight = GetRowHeight(layoutDefinition); // Calculate whitespace int rowCountInColumn = Math.Min(layoutDefinition.RowCount, layoutDefinition.Rows.Count); double whitespace = (availableHeight - ((double)rowCountInColumn * rowHeight)) / (double)(rowCountInColumn + 1); double y = 0; double x = 0; double currentRowBegin = 0; double currentMaxX = 0; double maxy = 0; for (int rowIndex = 0; rowIndex < layoutDefinition.Rows.Count; rowIndex++) { RibbonToolBarRow row = layoutDefinition.Rows[rowIndex]; x = currentRowBegin; if (rowIndex % rowCountInColumn == 0) { // Reset vars at new column x = currentRowBegin = currentMaxX; y = 0; if (rowIndex != 0) { #region Add separator Separator separator = null; if (!separatorCache.TryGetValue(rowIndex, out separator)) { separator = new Separator(); separator.Style = SeparatorStyle; separatorCache.Add(rowIndex, separator); } if (measure) { separator.Height = availableHeight - separator.Margin.Bottom - separator.Margin.Top; separator.Measure(availableSize); } if (arrange) { separator.Arrange(new Rect(x, y, separator.DesiredSize.Width, separator.DesiredSize.Height)); } x += separator.DesiredSize.Width; if (addchildren) { // Add control in the children AddVisualChild(separator); AddLogicalChild(separator); actualChildren.Add(separator); } #endregion } } y += whitespace; // Measure & arrange new row for (int i = 0; i < row.Children.Count; i++) { if (row.Children[i] is RibbonToolBarControlDefinition) { // Control Definition Case RibbonToolBarControlDefinition controlDefinition = (RibbonToolBarControlDefinition)row.Children[i]; FrameworkElement control = GetControl(controlDefinition); if (control == null) { continue; } if (addchildren) { // Add control in the children AddVisualChild(control); AddLogicalChild(control); actualChildren.Add(control); } if (measure) { // Apply Control Definition Properties RibbonControl ribbonControl = control as RibbonControl; if (ribbonControl != null) { ribbonControl.Size = controlDefinition.Size; } control.Width = controlDefinition.Width; control.Measure(availableSize); } if (arrange) { control.Arrange(new Rect(x, y, control.DesiredSize.Width, control.DesiredSize.Height)); } x += control.DesiredSize.Width; } if (row.Children[i] is RibbonToolBarControlGroupDefinition) { // Control Definition Case RibbonToolBarControlGroupDefinition controlGroupDefinition = (RibbonToolBarControlGroupDefinition)row.Children[i]; RibbonToolBarControlGroup control = GetControlGroup(controlGroupDefinition); if (addchildren) { // Add control in the children AddVisualChild(control); AddLogicalChild(control); actualChildren.Add(control); } if (measure) { // Apply Control Definition Properties control.IsFirstInRow = (i == 0); control.IsLastInRow = (i == row.Children.Count - 1); control.Measure(availableSize); } if (arrange) { control.Arrange(new Rect(x, y, control.DesiredSize.Width, control.DesiredSize.Height)); } x += control.DesiredSize.Width; } } y += rowHeight; if (currentMaxX < x) { currentMaxX = x; } if (maxy < y) { maxy = y; } } return(new Size(currentMaxX, maxy + whitespace)); }