Skip to content

Commit

Permalink
Fixes #510 by recording which menu items where opened
Browse files Browse the repository at this point in the history
  • Loading branch information
batzen committed Feb 15, 2018
1 parent 176eee0 commit 25029c8
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 21 deletions.
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## 6.0.1 (preview)

- ### Bug fixes
- [#510](../../issues/510) - Submenus in DropDownButton are not opened each time
- [#511](../../issues/511) - Binding on RibbonWindow.Icon not working
- [#512](../../issues/512) - Ideal text color should match the colors in the ribbon
- [#513](../../issues/513) - Hovering causes flickering of ribbon backstage menu items
Expand Down
95 changes: 74 additions & 21 deletions Fluent.Ribbon/Controls/DropDownButton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ namespace Fluent
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Windows;
Expand Down Expand Up @@ -39,6 +40,8 @@ public class DropDownButton : ItemsControl, IQuickAccessItemProvider, IRibbonCon

private UIElement buttonBorder;

private readonly Stack<WeakReference<MenuItem>> openMenuItems = new Stack<WeakReference<MenuItem>>();

#endregion

#region Properties
Expand Down Expand Up @@ -358,6 +361,9 @@ static DropDownButton()
ToolTipService.Attach(type);
PopupService.Attach(type);
ContextMenuService.Attach(type);

//EventManager.RegisterClassHandler(type, System.Windows.Controls.MenuItem.SubmenuOpenedEvent, new RoutedEventHandler(OnSubmenuOpened));
//EventManager.RegisterClassHandler(type, System.Windows.Controls.MenuItem.SubmenuClosedEvent, new RoutedEventHandler(OnSubmenuClosed));
}

/// <summary>
Expand All @@ -369,6 +375,9 @@ public DropDownButton()

this.Loaded += this.OnLoaded;
this.Unloaded += this.OnUnloaded;

this.AddHandler(System.Windows.Controls.MenuItem.SubmenuOpenedEvent, new RoutedEventHandler(this.OnSubmenuOpened));
this.AddHandler(System.Windows.Controls.MenuItem.SubmenuClosedEvent, new RoutedEventHandler(this.OnSubmenuClosed));
}

private void OnLoaded(object sender, RoutedEventArgs e)
Expand Down Expand Up @@ -558,7 +567,7 @@ protected override void OnKeyDown(KeyEventArgs e)

var container = this.ItemContainerGenerator.ContainerFromIndex(0);

NavigateToContainer(container);
NavigateToContainer(container, FocusNavigationDirection.Down);

handled = true;
}
Expand All @@ -573,7 +582,7 @@ protected override void OnKeyDown(KeyEventArgs e)

var container = this.ItemContainerGenerator.ContainerFromIndex(this.Items.Count - 1);

NavigateToContainer(container);
NavigateToContainer(container, FocusNavigationDirection.Up);

handled = true;
}
Expand Down Expand Up @@ -604,7 +613,7 @@ protected override void OnKeyDown(KeyEventArgs e)
base.OnKeyDown(e);
}

private static void NavigateToContainer(DependencyObject container)
private static void NavigateToContainer(DependencyObject container, FocusNavigationDirection focusNavigationDirection = FocusNavigationDirection.Down)
{
var element = container as FrameworkElement;

Expand All @@ -619,12 +628,7 @@ private static void NavigateToContainer(DependencyObject container)
}
else
{
var predicted = element.PredictFocus(FocusNavigationDirection.Down);

if (predicted is MenuBase == false)
{
element.MoveFocus(new TraversalRequest(FocusNavigationDirection.Down));
}
element.MoveFocus(new TraversalRequest(focusNavigationDirection));
}
}

Expand All @@ -644,12 +648,6 @@ public virtual KeyTipPressedResult OnKeyTipPressed()
{
this.IsDropDownOpen = true;

if (this.DropDownPopup?.Child != null)
{
Keyboard.Focus(this.DropDownPopup.Child);
this.DropDownPopup.Child.MoveFocus(new TraversalRequest(FocusNavigationDirection.First));
}

return new KeyTipPressedResult(true, true);
}

Expand Down Expand Up @@ -748,16 +746,31 @@ private static void OnIsDropDownOpenChanged(DependencyObject d, DependencyProper
}
}

// Handles drop down closed
private void OnDropDownClosed()
/// <summary>
/// Called when drop down opened.
/// </summary>
protected virtual void OnDropDownOpened()
{
this.DropDownClosed?.Invoke(this, EventArgs.Empty);
this.DropDownOpened?.Invoke(this, EventArgs.Empty);
}

// Handles drop down opened
private void OnDropDownOpened()
/// <summary>
/// Called when drop down closed.
/// </summary>
protected virtual void OnDropDownClosed()
{
this.DropDownOpened?.Invoke(this, EventArgs.Empty);
foreach (var openMenuItem in this.openMenuItems.ToArray())
{
MenuItem menuItem;
if (openMenuItem.TryGetTarget(out menuItem))
{
menuItem.IsSubmenuOpen = false;
}
}

this.openMenuItems.Clear();

this.DropDownClosed?.Invoke(this, EventArgs.Empty);
}

#endregion
Expand Down Expand Up @@ -891,5 +904,45 @@ protected override IEnumerator LogicalChildren
}
}
}

#region MenuItem workarounds

//private static void OnSubmenuOpened(object sender, RoutedEventArgs e)
//{
// var menuItem = e.OriginalSource as MenuItem;
// if (menuItem != null)
// {
// ((ApplicationMenu)sender).openMenuItems.Push(new WeakReference<MenuItem>(menuItem));
// }
//}

//private static void OnSubmenuClosed(object sender, RoutedEventArgs e)
//{
// var applicationMenu = (ApplicationMenu)sender;

// if (applicationMenu.openMenuItems.Count > 0)
// {
// applicationMenu.openMenuItems.Pop();
// }
//}

private void OnSubmenuOpened(object sender, RoutedEventArgs e)
{
var menuItem = e.OriginalSource as MenuItem;
if (menuItem != null)
{
this.openMenuItems.Push(new WeakReference<MenuItem>(menuItem));
}
}

private void OnSubmenuClosed(object sender, RoutedEventArgs e)
{
if (this.openMenuItems.Count > 0)
{
this.openMenuItems.Pop();
}
}

#endregion MenuItem workarounds
}
}

0 comments on commit 25029c8

Please sign in to comment.