microsoft / microsoft-ui-xaml

Windows UI Library: the latest Windows 10 native controls and Fluent styles for your applications
MIT License
6.33k stars 676 forks source link

Add multi-level hierarchy to NavigationView #79

Closed YuliKl closed 4 years ago

YuliKl commented 5 years ago

Proposal: Add multi-level hierarchy to NavigationView

Spec for this feature is available for review here.

Summary

Today, NavigationView's menu is a flat list of destinations. Adding hierarchy to the navigation menu would enable showing top-level categories and child sub-categories in the same place, which would help clarify for users the overall structure of the app.

Rationale

It’s common for complex apps to want to show multiple levels of navigation items. Although it’s possible to achieve hierarchy in the navigation pane today by placing the TreeView control into NavigationView’s PaneCustomContent area, there are multiple drawbacks to this approach. From the UI perspective, TreeView behaves poorly in NavigationView’s LeftCompact mode, and is not feasible in Top mode. For the developer, switching from NavigationView’s MenuItems list to a TreeView requires significant rewrites of the underlying data model. By providing a hierarchical solution directly within NavigationView we can eliminate implementation cliffs, significantly improve the user experience, and provide consistency across the app ecosystem.

Functional Requirements

# Feature Priority
1 NavigationViewItem supports any number of child items in both Left and Top NavigationView modes Must
2 Child items can be declared in markup Must
3 NavigationView continues to support data binding for all its MenuItems Must
4 Child items can be added or removed dynamically Must
5 Selecting an item with children will show/hide the child items Must
6 When the NavigationView Pane is closed, an item will appear selected if either itself or one of its child items is selected Must
7 Hierarchical items' keyboard behavior matches TreeView's (with some adjustments for Top vs Left NavigationView) Must
8 Items with children draw a chevron as a visual indicator that they can be expanded/collapsed Must
9 The chevron changes orientation based on whether the item is open or closed Should
10 Hierarchical items' open/close animations feel like they’re part of the same system as TreeView and MenuFlyoutSubItem animations Should
11 Support for "accordion" behavior which makes it easy for apps to show at most one expanded parent item at a time Should

Usage Examples

Create a hierarchical NavigationView in markup. This sample has two top-level categories, Home and Collections. The Collections item can be expanded to show its child sub-categories, Bookshelf and Mail.

<muxc:NavigationView>
    <muxc:NavigationView.MenuItems>
        <muxc:NavigationViewItem Content="Home" Icon="Home" ToolTipService.ToolTip="Home"/>
        <muxc:NavigationViewItem Content="Collections" 
                               Icon="Keyboard" ToolTipService.ToolTip="Collections">
            <muxc:NavigationViewItem.MenuItems>
                <muxc:NavigationViewItem Content="Bookshelf" 
                                    Icon="Library" ToolTipService.ToolTip="Bookshelf"/>
                <muxc:NavigationViewItem Content="Mail" 
                                    Icon="Mail" ToolTipService.ToolTip="Mail"/>
            </muxc:NavigationViewItem.MenuItems>
        </muxc:NavigationViewItem>                        
    </muxc:NavigationView.MenuItems>
</muxc:NavigationView>

Detailed Feature Design

Design mockups

These comps are not finalized and are shown here to illustrate the visual direction we're proposing. image image

Proposed API

Additions to existing NavigationViewItem class

public class NavigationViewItem : NavigationViewItemBase
{
    bool HasUnrealizedChildren { get; set; }
    bool IsChildSelected { get; set; }
    bool IsExpanded { get; set; }

    IList<Object> MenuItems { get; }
    Object MenuItemsSource { get; set; }
}

Additions to existing NavigationView class

public class NavigationView : ContentControl
{
    TypedEventHandler<NavigationView, NavigationViewExpandingEventArgs> Expanding;
    TypedEventHandler<NavigationView, NavigationViewCollapsedEventArgs> Collapsed;

    public void Expand(NavigationViewItem item);
    public void Collapse(NavigationViewItem item);

    bool AllowMultipleExpandedItems { get; set; }
}
public sealed class NavigationViewExpandingEventArgs
{
    NavigationViewItemBase Item { get; }
}

public sealed class NavigationViewCollapsedEventArgs
{
    NavigationViewItemBase Item { get; }
}

Open Questions

  1. When NavigationView is in LeftCompact or Top modes, should items with children expand on mouse hover or mouse click? Discussion of Pros and Cons:

    • Typically, Xaml controls show a hover state (e.g. reveal highlight) but don't change the content displayed to users. Notable exceptions to this rule of thumb are MenuFlyoutSubItem and MenuBar after the first click.
    • Showing a flyout with child items on hover improves discoverability. Chevrons are likely to be omitted in LeftCompact mode, so users would not be able to tell just by looking whether an item has children.
    • Showing a flyout on hover may be perceived by users as a more responsive behavior that saves them an unnecessary click.
    • Showing a flyout on hover has the potential to annoy users. One mitigation is to introduce a short delay before showing the flyout. Another mitigation is to follow the MenuBar behavior - show flyouts with children on hover only after the user has clicked on another parent item.
    • If showing flyout on hover, there's risk in defining and implementing the correct flyout dismiss behavior. Light dismiss gestures for dismissing a flyout that the user actively invoked are well understood. New lighter-dismiss behavior (e.g. moving the pointer outside the flyout) is not yet defined.
  2. Ensure Gamepad experience is defined.

Release Checklists

Prerelease readiness

LanceMcCarthy commented 5 years ago

Why not let the Hover/Click option be settable? This would useful if the setting could be applied to when the NavigationView's Primary and Secondary items have different use-cases.

Mixed Use Scenario:

However, there is one complication for this case, it might cause UX dissonance and the user might be confused that the menus operate differently.

As far as the hover delay, also expose this value as a DependencyProperty in case the delay is unwanted.

YuliKl commented 5 years ago

@LanceMcCarthy, the UX dissonance you mentioned is exactly my concern about making the hover/click option settable. I don't want to confuse users with some UWP apps having one behavior while other UWP apps show something different. So ideally this behavior would be policy at the control level that's kept consistent for all instances of NavigationView. And I would prefer to avoid exposing the hover delay for a similar reason. The TooltipService delay before showing a ToolTip isn't settable, and I think works well for our users. I would prefer to keep NavigationView's delay similarly consistent (assuming that we agree that a delay would be appropriate).

I'm not quite following the mixed use scenario and would love your help understanding it better. Maybe a rudimentary diagram of the menu would help illustrate the scenario?

LanceMcCarthy commented 5 years ago

I digress. After playing with several apps, including the Windows 10 Start Menu, I think any hover is a bad idea. Let the Tooltip take that responsibility.

Take the following steps to repeat the experience:

1 - Open Start Menu 2 - Let Tooltip show the button's target 3A - Clicking Settings navigates to a target 3B - Clicking the profile opens a flyout (you can substitute nested NavView menu for this)

image

The user expects the click to bring them to the target, or show them additional targets. While the hover shows the tooltip.

michael-hawker commented 5 years ago

It'd be nice to have a setting to allow the Parent to be clickable and navigable separate from expansion. Some apps like to have a 'parent' page for things, but then still allow for sub-navigation. Or the sub-navigation is just an anchor on the Parent page.

gcaughey commented 5 years ago

I like the hierarchical idea very much and especially for LOB apps coming from the WinForms world. For this scenario though I wouldn't want the hover behavior - I think it would confuse these very users. If implemented at all, please make it opt-in.

What would be the appearance of child items if no icon is provided? Just the text?

alvinashcraft commented 5 years ago

I agree with @gcaughey that this is a great option for those trying to find a path forward from WinForms apps. I work on a large app that uses a 3rd party WinForms treeview control for this kind of navigation pattern.

I imagine it would be pretty easy to customize the child items' template to have different appearances. We have sections in our tree that need to be bolded to indicate defaulted data has been entered, or it may have multiple icons to indicate things like required fields or data entered by other users is present.

contextfree commented 5 years ago

Interesting to see MenuBar-like "scrubbable" behavior treated as a variant of auto-expand on hover - I've never thought of them that way before, but, now that you've presented it that way, I see it does make sense logically. However, I wonder if most users might react to them very differently as well - scrubbability is familiar, not just from the UWP MenuBar but in Windows menu bars in general going back to the earliest versions of Windows (and other desktop GUIs). It's very useful for fluently ( :) ) exploring and learning what options, commands or places exist in an application. I think it might be the best option, providing most of the benefits from auto-expand on hover, avoiding most of the problems, and being more consistent with user expectations.

If mouse scrubbability is implemented, I wonder if it might also be good to provide a form of scrubbability for touch, by expanding the first submenu on initial touch down instead of touch up, and then expanding further submenus on "finger entered" until the finger is lifted. This would conflict with scrolling, so it might have to be disabled if the nav view is scrollable, but a scrollable nav view might be enough of an edge case that the inconsistency that introduces might not be too bad.

mdtauk commented 5 years ago

Will this work with mixed Navigation, so top level items, and some second level?

Will there be Tertiary level items supported?

How do you handle the selection indicator for when the current page is nested? Should there be a differentiation in how it is displayed?

mrlacey commented 5 years ago

I'd avoid hover on expand from an accessibility perspective so the menu won't change while I'm slowly moving my mouse cursor down the list or stop to think if I'm over the item I want. Many websites have been very bad at changing multi-level menus as the mouse cursor is moved over them and it's repeatedly cited as a bad UX and accessibility practice.

I'd also like to be able to have the secondary items support binding. That is how I'd like to use them for scenarios like an MRU or items that are only available under certain conditions.

michael-hawker commented 5 years ago

Agree with @mrlacey, the worst UI is one that changes just as you go to click on something...

YuliKl commented 5 years ago

Thank you everyone for your input! Sounds like expanding on hover is not the way to go. The scrubbing behavior @contextfree described is more appealing, and we'll consider adding it after an initial drop of this feature becomes available.

Changing the data template of NavigationViewItems will continue to be supported, so apps requiring a unique look to items have a straight-forward path to accomplish this. Nesting items N-levels deep will also be supported (although not recommended). We're still working on finalizing the visual design but plan on drawing the selection indicator next to or underneath the top-level parent, whether it's the parent or one of its collapsed/not visible children that is currently selected.

fmassicci commented 5 years ago

Where is the example?

YuliKl commented 5 years ago

@fmassicci - Which example are you looking for? Hierarchical NavigationView is still in progress and we don't have an example of this working just yet.

fmassicci commented 5 years ago

Thank you! Excuse me, we look forward to this innovation, which is fundamental to our small project.

Inviato da Postahttps://go.microsoft.com/fwlink/?LinkId=550986 per Windows 10


Da: Yulia notifications@github.com Inviato: Tuesday, April 30, 2019 6:33:26 PM A: Microsoft/microsoft-ui-xaml Cc: Fabio; Mention Oggetto: Re: [Microsoft/microsoft-ui-xaml] Add multi-level hierarchy to NavigationView (#79)

@fmassiccihttps://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ffmassicci&data=02%7C01%7C%7Ca2d5279fee7f42289cd008d6cd89923d%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636922388073577266&sdata=clxKGlKDfvdZEbZO9c94VF6SmpTNOEofGBONjWcBnns%3D&reserved=0 - Which example are you looking for? Hierarchical NavigationView is still in progress and we don't have an example of this working just yet.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FMicrosoft%2Fmicrosoft-ui-xaml%2Fissues%2F79%23issuecomment-488022853&data=02%7C01%7C%7Ca2d5279fee7f42289cd008d6cd89923d%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636922388073587265&sdata=1BMZJhdF4z%2BxbX55uCh%2BwT7QKb0UQAzJSHyHqT1%2B0Qs%3D&reserved=0, or mute the threadhttps://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FABQTM63CTZXQNEI54PW5F7LPTBYFNANCNFSM4GKJXPYQ&data=02%7C01%7C%7Ca2d5279fee7f42289cd008d6cd89923d%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636922388073607281&sdata=dVxFGujRn23DSZpIawDeiUbdClynkWgZ4c2eMF%2F6nvc%3D&reserved=0.

Joel-Intact commented 5 years ago

I agree with @fmassicci, this would be greatly welcomed by UWP developers! (And we're exited and also eagerly waiting for this feature as well) 👍

YuliKl commented 5 years ago

Thank you, @fmassicci and @Joel-Intact, for your feedback. Your opinions really help in prioritizing hierarchical NavigationView work relative to other features assigned to my team. Keep your 👍 and your thoughts coming!

carloseduardosx commented 5 years ago

I agree with @fmassicci and @Joel-Intact, I'm working on a react-native-windows project and I'm creating a port of this component to the RN layer, this feature would be extremely welcomed by my team, we're looking forward to this feature.

knightmeister commented 5 years ago

Hi there, I could really use this and was wondering if it's on the roadmap at all. If it is, when might we expect to be able to use it?

YuliKl commented 5 years ago

@knightmeister, I'm hoping to see this feature release as part of WinUI 2.3, so within the next few months.

Poopooracoocoo commented 5 years ago

Would clicking and dragging to select work in the compact mode? #815

YuliKl commented 5 years ago

Would clicking and dragging to select work in the compact mode? #815

This is currently not in scope. It's something we've discussed and will likely add at a later time. Because the click-and-drag doesn't work for free, it feels more pressing to focus on shipping hierarchical nav as a whole before zeroing in on these types of finer interaction details.

zawawimanja commented 5 years ago

so when in the new feature will be released?? any samples??

jevansaks commented 5 years ago

@ojhad is working on this now; I expect he'll have some early bits to share in a couple weeks.

shaheedmalik commented 5 years ago

This is a good idea as we have already seen a use case for in the Power button on the Start Menu and Microsoft Store.

image

image

YuliKl commented 5 years ago

@shaheedmalik, for even more parity with the Start menu, we also have #1103 on the backlog. I would love to hear your thoughts about that proposal as well.

michael-hawker commented 4 years ago

I'm not sure why I didn't think to call this out sooner, we also exploited the NavigationView to have a deeper hierarchy presented within the Windows Community Toolkit sample app:

image

image

However, we just used the NavigationView for the top-level menu, and then put a GridView that we pop-down for the content that then does the division of Sub-categories to actual clickable sample items.

Code link

fmassicci commented 4 years ago

Good morning, about the Add multi-level hierarchy to NavigationView what's the point? Thank you