Represent base class for Fluent controls
Inheritance: System.Windows.Controls.Control, ICommandSource, IQuickAccessItemProvider, IRibbonControl
示例#1
0
        /// <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();
        }
示例#2
0
        /// <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;
        }
示例#3
0
        /// <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);
        }
示例#4
0
        // 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();
        }
示例#5
0
        /// <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();
        }
示例#6
0
        /// <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);
        }
示例#7
0
        /// <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);
        }
示例#8
0
        /// <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();
        }
示例#9
0
        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();
        }
示例#10
0
        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();
        }
示例#11
0
        /// <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();
        }
示例#12
0
        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();
        }
示例#13
0
        /// <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));
        }