コード例 #1
0
        /// <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);
        }