private void TransferPseudoInheritedProperties()
 {
     if (_templateRoot != null)
     {
         // Ribbon is an inherited property. In non-MVVM scenarios where
         // controls are directly added under RibbonGroup in XAML, RibbonGroup
         // is the logical parent of those controls and they get the value
         // of RibbonParent set from their logical parent. When a RibbonGroup
         // get collapsed and its template changes, due to a bug in framework
         // the inheritance value of those controls is lost during visual tree
         // change and never again gets updated. The workaround is to set the
         // local value on those controls from RibbonContentPresenter which
         // would be their visual parent. This works because Ribbon property is
         // readonly.
         RibbonControlService.SetRibbon(_templateRoot, RibbonControlService.GetRibbon(this));
         RibbonHelper.TransferPseudoInheritedProperties(this, _templateRoot);
     }
 }
Exemplo n.º 2
0
        /// <summary>
        ///   Invoked whenever the control's template is applied.
        /// </summary>
        public override void OnApplyTemplate()
        {
            if (Level == RibbonApplicationMenuItemLevel.Top)
            {
                RibbonHelper.UnhookPopupForTopLevelMenuItem(this);
            }

            base.OnApplyTemplate();

            if (Level == RibbonApplicationMenuItemLevel.Top)
            {
                // Bind properties such as PlacementTarget, Height and
                // Width for the submenu Popup to the parent
                // RibbonApplicationMenu's SubmenuPlaceholder element.

                RibbonHelper.HookPopupForTopLevelMenuItem(this, ParentItemsControl);
            }
        }
 protected override void OnKeyTipAccessed(KeyTipAccessedEventArgs e)
 {
     if (e.OriginalSource == this)
     {
         if (CanOpenSubMenu)
         {
             FocusOrSelect();
             IsSubmenuOpen = true;
             RibbonHelper.NavigateToNextMenuItemOrGallery(this, -1, BringIndexIntoView);
             UIElement popupChild = Popup.TryGetChild();
             if (popupChild != null)
             {
                 KeyTipService.SetIsKeyTipScope(popupChild, true);
                 e.TargetKeyTipScope = popupChild;
             }
         }
         e.Handled = true;
     }
 }
Exemplo n.º 4
0
        protected override Size MeasureOverride(Size availableSize)
        {
            Size desiredSize = new Size();
            IContainsStarLayoutManager iContainsStarLayoutManager = (IContainsStarLayoutManager)this;

            RibbonHelper.InitializeStarLayoutManager(this);
            bool isStarLayoutPass = (iContainsStarLayoutManager.StarLayoutManager == null ? false : iContainsStarLayoutManager.StarLayoutManager.IsStarLayoutPass);

            if (!isStarLayoutPass)
            {
                desiredSize = NonStarPassMeasure(availableSize);
            }
            else
            {
                desiredSize = StarMeasurePass(availableSize);
            }

            return(desiredSize);
        }
Exemplo n.º 5
0
        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);

            if (!e.Handled)
            {
                DependencyObject focusedElement = Keyboard.FocusedElement as DependencyObject;
                RibbonTabHeader  tabHeader      = RibbonTabHeader;
                if (e.Key == Key.Up && focusedElement != null && tabHeader != null)
                {
                    // On arrow up key press if the focus goes out of the tab,
                    // then force it to move to the corresponding TabHeader.
                    DependencyObject upObj = RibbonHelper.PredictFocus(focusedElement, FocusNavigationDirection.Up);
                    if (!RibbonHelper.IsAncestorOf(this, upObj))
                    {
                        if (tabHeader.Focus())
                        {
                            e.Handled = true;
                        }
                    }
                }
            }
        }
Exemplo n.º 6
0
        protected override void ClearContainerForItemOverride(DependencyObject element, object item)
        {
            base.ClearContainerForItemOverride(element, item);

            RibbonHelper.ClearPseudoInheritedProperties(element);
        }
Exemplo n.º 7
0
        private void OnClickThrough(MouseButtonEventArgs e)
        {
            UIElement popupChild = _overflowPopup.TryGetChild();

            RibbonHelper.HandleClickThrough(this, e, popupChild);
        }
Exemplo n.º 8
0
 protected override void OnPreviewKeyDown(KeyEventArgs e)
 {
     if (e.Handled)
     {
         return;
     }
     if (e.Key == Key.Down)
     {
         DependencyObject element = e.OriginalSource as DependencyObject;
         if (element != null)
         {
             UIElement footerPaneHost = FooterPaneHost;
             if (footerPaneHost != null &&
                 footerPaneHost.IsKeyboardFocusWithin &&
                 TreeHelper.IsVisualAncestorOf(footerPaneHost, element))
             {
                 DependencyObject nextFocus = RibbonHelper.PredictFocus(element, FocusNavigationDirection.Down);
                 if (nextFocus == null ||
                     nextFocus == element)
                 {
                     // If the focus is on the last element of footer pane,
                     // then try moving focus into items pane and then into
                     // auxiliary pane if needed.
                     if (ItemsPaneMoveFocus(FocusNavigationDirection.First) ||
                         AuxiliaryPaneMoveFocus(FocusNavigationDirection.First))
                     {
                         e.Handled = true;
                     }
                 }
             }
         }
     }
     else if (e.Key == Key.Up)
     {
         UIElement popupChild = _popup.TryGetChild();
         if (popupChild != null &&
             !popupChild.IsKeyboardFocusWithin)
         {
             // If the popup does not have focus with in then try moving focus to
             // last element of FooterPane and then to the last element of
             // auxiliary pane if needed.
             if (FooterPaneMoveFocus(FocusNavigationDirection.Last) ||
                 AuxiliaryPaneMoveFocus(FocusNavigationDirection.Last))
             {
                 e.Handled = true;
             }
         }
         else
         {
             DependencyObject element = e.OriginalSource as DependencyObject;
             if (element != null)
             {
                 UIElement auxilaryPaneHost = AuxiliaryPaneHost;
                 if (auxilaryPaneHost != null &&
                     auxilaryPaneHost.IsKeyboardFocusWithin &&
                     TreeHelper.IsVisualAncestorOf(auxilaryPaneHost, element))
                 {
                     DependencyObject nextFocus = RibbonHelper.PredictFocus(element, FocusNavigationDirection.Up);
                     if (nextFocus == null ||
                         nextFocus == element)
                     {
                         // If the focus is on last first element of auxiliary pane,
                         // then try moving focus to last element of Items Pane and
                         // then to last element of FooterPane if needed.
                         if (ItemsPaneMoveFocus(FocusNavigationDirection.Last) ||
                             FooterPaneMoveFocus(FocusNavigationDirection.Last))
                         {
                             e.Handled = true;
                         }
                     }
                 }
             }
         }
     }
     else if (e.Key == Key.Left ||
              e.Key == Key.Right)
     {
         DependencyObject element = e.OriginalSource as DependencyObject;
         if (element != null)
         {
             if ((e.Key == Key.Left) == (FlowDirection == FlowDirection.LeftToRight))
             {
                 UIElement auxilaryPaneHost = AuxiliaryPaneHost;
                 if (auxilaryPaneHost != null &&
                     auxilaryPaneHost.IsKeyboardFocusWithin &&
                     TreeHelper.IsVisualAncestorOf(auxilaryPaneHost, element))
                 {
                     // If the effective key is left and the focus is on left most element
                     // of auxiliary pane, then move focus to nearest element to the left of
                     // auxiliarypane.
                     DependencyObject nextFocus = RibbonHelper.PredictFocus(element, FocusNavigationDirection.Last);
                     if (nextFocus != null &&
                         !TreeHelper.IsVisualAncestorOf(auxilaryPaneHost, nextFocus))
                     {
                         if (RibbonHelper.Focus(nextFocus))
                         {
                             e.Handled = true;
                         }
                     }
                 }
             }
             else if (e.Key == Key.Left)
             {
                 ScrollViewer subMenuScrollViewer = SubMenuScrollViewer;
                 if (subMenuScrollViewer != null &&
                     subMenuScrollViewer.IsKeyboardFocusWithin &&
                     TreeHelper.IsVisualAncestorOf(subMenuScrollViewer, element))
                 {
                     // If the flow direction is RightToLeft and the key is Left,
                     // and the focus is in items pane, move the the focus outside teh
                     // items pane if needed.
                     RibbonMenuItem menuItem = element as RibbonMenuItem;
                     if (menuItem == null)
                     {
                         menuItem = TreeHelper.FindVisualAncestor <RibbonMenuItem>(element);
                     }
                     if (menuItem != null &&
                         !menuItem.CanOpenSubMenu)
                     {
                         DependencyObject nextFocus = menuItem.PredictFocus(FocusNavigationDirection.Right);
                         if (nextFocus != null)
                         {
                             if (RibbonHelper.Focus(nextFocus))
                             {
                                 e.Handled = true;
                             }
                         }
                     }
                 }
             }
         }
     }
     base.OnPreviewKeyDown(e);
 }
Exemplo n.º 9
0
        /// <summary>
        ///     Called by consumers of TextSearchInternal when a TextInput event is received
        ///     to kick off the algorithm.
        /// </summary>
        /// <param name="nextChar"></param>
        /// <returns></returns>
        internal bool DoSearch(string nextChar)
        {
            bool repeatedChar = false;

            int startItemIndex = 0;

            ItemCollection itemCollection = _attachedTo.Items as ItemCollection;

            // If TextSearchInternal is not active, then we should start
            // the search from the beginning.  If it is active, we should
            // start the search from the currently-matched item.
            if (IsActive)
            {
                // ISSUE: This falls victim to duplicate elements being in the view.
                //        To mitigate this, we could remember ItemUI ourselves.

                startItemIndex = MatchedItemIndex;
            }

            // If they pressed the same character as last time, we will do the fallback search.
            //     Fallback search is if they type "bob" and then press "b"
            //     we'll look for "bobb" and when we don't find it we should
            //     find the next item starting with "bob".
            if (_charsEntered.Count > 0 &&
                (String.Compare(_charsEntered[_charsEntered.Count - 1], nextChar, true, GetCulture(_attachedTo)) == 0))
            {
                repeatedChar = true;
            }

            // Get the primary TextPath from the ItemsControl to which we are attached.
            string primaryTextPath = GetPrimaryTextPath(_attachedTo, false);

            bool wasNewCharUsed = false;

            int matchedItemIndex = FindMatchingPrefix(_attachedTo, primaryTextPath, Prefix, nextChar, startItemIndex, repeatedChar, ref wasNewCharUsed);

            // If there was an item that matched, move to that item in the collection
            if (matchedItemIndex != -1)
            {
                // Don't have to move currency if it didn't actually move.
                // startItemIndex is the index of the current item only if IsActive is true,
                // So, we have to move currency when IsActive is false.
                if (!IsActive || matchedItemIndex != startItemIndex)
                {
                    object matchedItem = itemCollection[matchedItemIndex];
                    // Let the control decide what to do with matched-item

                    RibbonHelper.NavigateToItem(_attachedTo, matchedItemIndex, null);

                    // Store current match
                    MatchedItemIndex = matchedItemIndex;
                }

                // Update the prefix if it changed
                if (wasNewCharUsed)
                {
                    AddCharToPrefix(nextChar);
                }

                // User has started typing (successfully), so we're active now.
                if (!IsActive)
                {
                    IsActive = true;
                }
            }

            // Reset the timeout and remember this character, but only if we're
            // active -- this is because if we got called but the match failed
            // we don't need to set up a timeout -- no state needs to be reset.
            if (IsActive)
            {
                ResetTimeout();
            }

            return(matchedItemIndex != -1);
        }
 private void OnRibbonGalleryCategoriesPanelLoaded(object sender, RoutedEventArgs e)
 {
     RibbonHelper.InitializeStarLayoutManager(this);
 }
Exemplo n.º 11
0
 protected override void OnLostKeyboardFocus(KeyboardFocusChangedEventArgs e)
 {
     base.OnLostKeyboardFocus(e);
     RibbonHelper.DisableFocusVisual(this);
 }
Exemplo n.º 12
0
 /// <summary>
 ///  Called when the container is being attached to the parent ItemsControl
 /// </summary>
 /// <param name="element"></param>
 /// <param name="item"></param>
 protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
 {
     base.PrepareContainerForItemOverride(element, item);
     RibbonHelper.SetApplicationMenuLevel(this.Level == RibbonApplicationMenuItemLevel.Top, element);
 }
Exemplo n.º 13
0
        /// <summary>
        /// In normal(Star) pass this panel behaves like a StackPanel but during Auto(non Star) pass
        /// It returns minimum Width and Height required to represent the children. There is another
        /// mode wherein it provides laying out mechanism for InRibbonGallery in INRibbon mode.
        /// </summary>
        /// <param name="availableSize"></param>
        /// <returns></returns>
        protected override Size MeasureOverride(Size availableSize)
        {
            RibbonGallery gallery = this.Gallery;

#if IN_RIBBON_GALLERY
            InRibbonGallery parentInRibbonGallery = gallery != null ? gallery.ParentInRibbonGallery : null;
            bool            isInInRibbonMode      = parentInRibbonGallery != null ? parentInRibbonGallery.IsInInRibbonMode : false;

            // For an InRibbonGallery rendering with IsDropDownOpen==true, we force gallery.ItemsPresenter's
            // MinWidth to be at least the value of IRG.ContentPresenter.ActualWidth.  This way, the IRG's popup
            // totally eclipses the IRG, which is required by the Office Fluent UI guidelines.
            if (gallery != null &&
                gallery.ItemsPresenter != null &&
                parentInRibbonGallery != null)
            {
                if (isInInRibbonMode && _irgIsConstrainingWidth)
                {
                    gallery.ItemsPresenter.MinWidth = _originalGalleryItemsPresenterMinWidth;
                    _irgIsConstrainingWidth         = false;
                }
                else if (parentInRibbonGallery.IsDropDownOpen && !_irgIsConstrainingWidth)
                {
                    _originalGalleryItemsPresenterMinWidth = gallery.ItemsPresenter.MinWidth;
                    double minWidthFromParent = parentInRibbonGallery.CalculateGalleryItemsPresenterMinWidth();
                    gallery.ItemsPresenter.MinWidth = Math.Max(minWidthFromParent, _originalGalleryItemsPresenterMinWidth);
                    _irgIsConstrainingWidth         = true;
                }
            }

            if (!isInInRibbonMode)
            {
#endif
            RibbonHelper.InitializeStarLayoutManager(this);
#if IN_RIBBON_GALLERY
        }
#endif

            IContainsStarLayoutManager iContainsStarLayoutManager = (IContainsStarLayoutManager)this;
            bool isStarLayoutPass = (iContainsStarLayoutManager.StarLayoutManager == null ? true : iContainsStarLayoutManager.StarLayoutManager.IsStarLayoutPass);

#if IN_RIBBON_GALLERY
            if (isInInRibbonMode)
            {
                PreComputeMaxRibbonGalleryItemWidthAndHeight();
                return(InRibbonGalleryModeMeasureOverride(availableSize));
            }
            else
            {
#endif
            if (isStarLayoutPass)
            {
                return(RealMeasureOverride(availableSize));
            }
            else
            {
                return(AutoPassMeasureOverride());
            }
#if IN_RIBBON_GALLERY
        }
#endif
        }
Exemplo n.º 14
0
 private void OnLoaded(object sender, RoutedEventArgs e)
 {
     RibbonHelper.FindAndHookPopup(this, ref _popup);
 }
Exemplo n.º 15
0
        /// <summary>
        ///     RibbonToolTip custom placement logic
        /// </summary>
        /// <param name="popupSize">The size of the popup.</param>
        /// <param name="targetSize">The size of the placement target.</param>
        /// <param name="offset">The Point computed from the HorizontalOffset and VerticalOffset property values.</param>
        /// <returns>An array of possible tooltip placements.</returns>

        private CustomPopupPlacement[] PlaceRibbonToolTip(Size popupSize, Size targetSize, Point offset)
        {
            UIElement placementTarget = this.PlacementTarget;
            double    belowOffsetY    = 0.0;
            double    aboveOffsetY    = 0.0;
            double    offsetX         = FlowDirection == FlowDirection.LeftToRight ? 0.0 : -popupSize.Width;

            if (IsPlacementTargetInRibbonGroup)
            {
                // If the PlacementTarget is within a RibbonGroup we proceed
                // with the custom placement policy.

                // Walk up the visual tree from PlacementTarget to find the Ribbon
                // if exists or the root element which is likely a PopupRoot.
                Ribbon           ribbon      = null;
                DependencyObject rootElement = null;
                DependencyObject element     = placementTarget;
                while (element != null)
                {
                    ribbon = element as Ribbon;
                    if (ribbon != null)
                    {
                        break;
                    }

                    rootElement = element;
                    element     = VisualTreeHelper.GetParent(element);
                }

                double           additionalOffset = 1.0;
                FrameworkElement referenceFE      = null;

                if (ribbon != null)
                {
                    additionalOffset = 0.0;
                    referenceFE      = ribbon;
                }
                else
                {
                    if (rootElement != null)
                    {
                        referenceFE = rootElement as FrameworkElement;
                    }
                }

                if (referenceFE != null)
                {
                    // When RibbonControl (PlacementTarget) is within a collapsed group RibbonToolTip is
                    // placed just below the Popup or just above the Popup (in case there is not enough
                    // screen space left below the Popup).

                    MatrixTransform transform = referenceFE.TransformToDescendant(placementTarget) as MatrixTransform;
                    if (transform != null)
                    {
                        MatrixTransform       deviceTransform = new MatrixTransform(RibbonHelper.GetTransformToDevice(referenceFE));
                        GeneralTransformGroup transformGroup  = new GeneralTransformGroup();
                        transformGroup.Children.Add(transform);
                        transformGroup.Children.Add(deviceTransform);

                        Point leftTop, rightBottom;
                        transformGroup.TryTransform(new Point(0, 0), out leftTop);
                        transformGroup.TryTransform(new Point(referenceFE.ActualWidth, referenceFE.ActualHeight), out rightBottom);

                        belowOffsetY = rightBottom.Y + additionalOffset;
                        aboveOffsetY = leftTop.Y - popupSize.Height - additionalOffset;
                    }
                }
            }
            else
            {
                // If PlacementTarget isn't within a RibbonGroup we shouldn't have
                // gotten here in the first place. But now that we are we will make
                // the best attempt at emulating PlacementMode.Bottom.
                FrameworkElement placementTargetAsFE = placementTarget as FrameworkElement;
                if (placementTargetAsFE != null)
                {
                    belowOffsetY = targetSize.Height;
                    aboveOffsetY = -popupSize.Height;
                }
            }

            // This is the prefered placement, below the ribbon for controls within Ribbon or below the Popup for controls within Popup.
            CustomPopupPlacement placementPreffered = new CustomPopupPlacement(new Point(offsetX, belowOffsetY), PopupPrimaryAxis.Horizontal);

            // This is a fallback placement, if the tooltip will not fit below the ribbon or Popup, place it above the ribbon or Popup.
            CustomPopupPlacement placementFallback = new CustomPopupPlacement(new Point(offsetX, aboveOffsetY), PopupPrimaryAxis.Horizontal);

            return(new CustomPopupPlacement[] { placementPreffered, placementFallback });
        }
Exemplo n.º 16
0
 public static void RemoveCloneHandler(DependencyObject element, RibbonQuickAccessToolBarCloneEventHandler handler)
 {
     RibbonHelper.RemoveHandler(element, CloneEvent, handler);
 }
 public static void RemoveDismissPopupHandler(DependencyObject element, RibbonDismissPopupEventHandler handler)
 {
     RibbonHelper.RemoveHandler(element, DismissPopupEvent, handler);
 }
Exemplo n.º 18
0
 protected override void OnKeyDown(KeyEventArgs e)
 {
     RibbonHelper.OnApplicationMenuItemUpDownKeyDown(e, this);
     base.OnKeyDown(e);
 }
Exemplo n.º 19
0
        /// <summary>
        /// TextSearchInternal in an ItemsControl containing ItemsControls as children (i.e. RibbonGallery)
        /// performs TextSearchInternal on the second level Items.
        /// </summary>
        /// <param name="nextChar"></param>
        /// <returns></returns>
        internal bool DoHierarchicalSearch(string nextChar)
        {
            bool repeatedChar = false;

            // If they pressed the same character as last time, we will do the fallback search.
            //     Fallback search is if they type "bob" and then press "b"
            //     we'll look for "bobb" and when we don't find it we should
            //     find the next item starting with "bob".
            if (_charsEntered.Count > 0 &&
                (String.Compare(_charsEntered[_charsEntered.Count - 1], nextChar, true, GetCulture(_attachedTo)) == 0))
            {
                repeatedChar = true;
            }

            bool wasNewCharUsed = false;

            int matchedItemIndex = -1;

            int startItemsControlIndex = 0;

            // If TextSearchInternal is not active, then we should start
            // the search from the beginning.  If it is active, we should
            // start the search from the ItemsControl containing the currently-matched item.
            if (IsActive)
            {
                startItemsControlIndex = MatchedItemsControlIndex;
            }

            int itemCount = _attachedTo.Items.Count;

            for (int currentIndex = startItemsControlIndex; currentIndex < itemCount;)
            {
                // Skip over filtered categories
                ItemsControl childItemsControl = _attachedTo.ItemContainerGenerator.ContainerFromIndex(currentIndex) as ItemsControl;
                if (childItemsControl != null && childItemsControl.Visibility == Visibility.Visible)
                {
                    int startItemIndex = 0;

                    // If TextSearchInternal is not active, then we should start
                    // the search from the beginning.  If it is active, we should
                    // start the search from the currently-matched item.
                    if (IsActive)
                    {
                        startItemIndex = MatchedItemIndex;
                    }

                    ItemCollection itemCollection = childItemsControl.Items as ItemCollection;

                    // Get the primary TextPath from the child ItemsControl
                    string primaryTextPath = GetPrimaryTextPath(childItemsControl, true);

                    matchedItemIndex = FindMatchingPrefix(childItemsControl, primaryTextPath, Prefix, nextChar, startItemIndex, repeatedChar, ref wasNewCharUsed,
                                                          /* hierarchicalSearch */ true,
                                                          /* fallbackFirstItem */ currentIndex != startItemsControlIndex);

                    // If there was an item that matched, move to that item in the collection
                    if (matchedItemIndex != -1)
                    {
                        // Don't have to move currency if it didn't actually move.
                        // startItemIndex is the index of the current item only if IsActive is true,
                        // So, we have to move currency when IsActive is false.
                        if (!IsActive || matchedItemIndex != startItemIndex || currentIndex != startItemsControlIndex)
                        {
                            object matchedItem = itemCollection[matchedItemIndex];

                            // Let the control decide what to do with matched-item
                            RibbonHelper.NavigateToItem(childItemsControl, matchedItemIndex, null);

                            // Store current match
                            MatchedItemIndex         = matchedItemIndex;
                            MatchedItemsControlIndex = currentIndex;
                        }

                        // Update the prefix if it changed
                        if (wasNewCharUsed)
                        {
                            AddCharToPrefix(nextChar);
                        }

                        // User has started typing (successfully), so we're active now.
                        if (!IsActive)
                        {
                            IsActive = true;
                        }
                    }

                    // Reset the timeout and remember this character, but only if we're
                    // active -- this is because if we got called but the match failed
                    // we don't need to set up a timeout -- no state needs to be reset.
                    if (IsActive)
                    {
                        ResetTimeout();
                    }

                    // Found a match so exit the loop.
                    if (matchedItemIndex != -1)
                    {
                        return(true);
                    }

                    // Reset matchedItemIndex because we are moving to the next childItemsControl
                    MatchedItemIndex = 0;
                }

                // Move next and wrap-around if we pass the end of the container.
                currentIndex++;
                if (currentIndex >= itemCount)
                {
                    currentIndex = 0;
                }

                // Stop where we started but only after the first pass
                // through the loop -- we should process the startItem.
                if (currentIndex == startItemsControlIndex)
                {
                    break;
                }
            }

            return(false);
        }
Exemplo n.º 20
0
        private static void AddToQATCanExecute(object sender, CanExecuteRoutedEventArgs args)
        {
            DependencyObject thatCanBeAddedToQat = MyRibbon.FindElementThatCanBeAddedToQAT(args.OriginalSource as DependencyObject);

            if (thatCanBeAddedToQat == null || RibbonControlService.GetQuickAccessToolBarId(thatCanBeAddedToQat) == null || RibbonHelper.ExistsInQAT(thatCanBeAddedToQat))
            {
                return;
            }
            args.CanExecute = true;
        }