/// <summary> /// Invoked when the QuickAccessToolbar's template is applied. /// </summary> public override void OnApplyTemplate() { base.OnApplyTemplate(); if (_mainPanel != null) { _mainPanel.Children.Clear(); } if (_overflowPanel != null) { _overflowPanel.Children.Clear(); } _mainPanel = GetTemplateChild(MainPanelTemplatePartName) as RibbonQuickAccessToolBarPanel; _overflowPanel = GetTemplateChild(OverflowPanelTemplatePartName) as RibbonQuickAccessToolBarOverflowPanel; _overflowPopup = GetTemplateChild(OverflowPopupTemplatePartName) as Popup; _overflowButton = GetTemplateChild(OverflowButtonTemplatePartName) as RibbonToggleButton; if (_overflowButton != null) { _overflowButton.ToolTipTitle = _overflowButtonToolTipText; } // Set KeyTipAutoGenerationElements property on self. IEnumerable <DependencyObject> keyTipAutoGenerationElements = new KeyTipAutoGenerationElements(this); KeyTipService.SetKeyTipAutoGenerationElements(this, keyTipAutoGenerationElements); if (_overflowPanel != null) { // Set KeyTipAutoGenerationElements property on overflow panel which helps // auto generation of keytips on elements of overflow. KeyTipService.SetKeyTipAutoGenerationElements(_overflowPanel, keyTipAutoGenerationElements); } }
// Basic algorithm: // For each child in GeneratedChildren... // If we are not sending items to overflow... // If the child is already in InternalChildren at the current index, do nothing. Otherwise... // If the child is in overlow panel at position 0, remove it and set IsOverflowItem = false. // Insert the child into InternalChildren at the current index. // Measure the child... // If the child fits, increment the panel's desired width by the child's width. // Otherwise... // Set sendToOverflow flag to start sending items to overflow. // Remove child and any other items beyond it from InternalChildren. // If we are sending items to overflow... // If child is not already in the overflow panel at overflowIndex, insert it. // Increment overflowIndex. // Set HasOverflowItems appropriately & invalidate the overflow panel's measure if necessary. protected override Size MeasureOverride(Size availableSize) { Size panelDesiredSize = new Size(); double maxExtent = availableSize.Width; bool sendToOverflow = false; UIElementCollection children = InternalChildren; List <UIElement> generatedItems = GeneratedChildren; int overflowIndex = 0; RibbonQuickAccessToolBarOverflowPanel overflowPanel = QAT == null ? null : QAT.OverflowPanel; for (int i = 0; i < generatedItems.Count; i++) { UIElement generatedChild = generatedItems[i]; Debug.Assert(generatedChild != null); if (!sendToOverflow) { if (i >= children.Count || !object.ReferenceEquals(children[i], generatedChild)) { if (overflowPanel != null && overflowPanel.Children.Count > 0 && object.ReferenceEquals(overflowPanel.Children[0], generatedChild)) { overflowPanel.Children.RemoveAt(0); RibbonQuickAccessToolBar.SetIsOverflowItem(generatedChild, false); } base.InsertInternalChild(i, generatedChild); } Size infinity = new Size(Double.PositiveInfinity, availableSize.Height); generatedChild.Measure(infinity); Size childDesiredSize = generatedChild.DesiredSize; double newExtent = panelDesiredSize.Width + childDesiredSize.Width; if (DoubleUtil.GreaterThan(newExtent, maxExtent)) { // It doesn't fit, send to overflow sendToOverflow = true; base.RemoveInternalChildRange(i, children.Count - i); } else { panelDesiredSize.Width = newExtent; panelDesiredSize.Height = Math.Max(panelDesiredSize.Height, childDesiredSize.Height); } } if (sendToOverflow) { Debug.Assert(overflowPanel.Children.Count >= overflowIndex, "overflowIndex should never get above overflowPanel.Children.Count"); if (overflowPanel != null && overflowPanel.Children.Count == overflowIndex || !object.ReferenceEquals(overflowPanel.Children[overflowIndex], generatedChild)) { overflowPanel.Children.Insert(overflowIndex, generatedChild); } RibbonQuickAccessToolBar.SetIsOverflowItem(generatedChild, true); overflowIndex++; } } // If necessary, set HasOverflowItems and invalidate the overflow panel's measure. if (QAT != null) { if (QAT.HasOverflowItems != sendToOverflow) { QAT.HasOverflowItems = sendToOverflow; // HasOverflowItems has changed, but the Grid that holds OverflowButtonHost does not automatically remeasure since it is already in its measure pass. // Therefore, we must dispatch a call to remeasure that Grid after this current pass has completed. Dispatcher.BeginInvoke((Action) delegate() { UIElement parent = VisualTreeHelper.GetParent(this) as UIElement; if (parent != null) { parent.InvalidateMeasure(); } }, DispatcherPriority.Normal, null); } if (sendToOverflow && QAT.OverflowPanel != null) { QAT.OverflowPanel.InvalidateMeasure(); } } #if DEBUG ValidateMeasure(); #endif return(panelDesiredSize); }