MvvmCross sidebar navigation for MvvmCross 5.x

I am using two types of navigation for my application, sidebar navigation and parent navigation at the same time. My app starts with a hamburger menu (sidebar).

The first item in the sidebar menu should reset the navigation stack and open the home view. The home controller must start navigating the root stack, so every button in the home view must open a new view, a button on a new view must open a different view, etc.

Every other item in the sidebar menu should open a new view as a dialog.

I am using MvvmCross 5.x and there is no sample 5.x compatible. Is there anyone who can point me to a useful sample?

+3


source to share


1 answer


At first I will assume that you are trying to implement this for iOS. In the case of Android, you can simply use the navigation drawer.

The sample on iOS has not yet converted to MvvmCross 5.x (I'll start doing this asap), however this should be trivial. Let me try to walk you through this:

  • Make sure you add the iOS MvvmCross support package to your iOS project: Install-Package MvvmCross.iOS.Support -Version 5.0.2

    (or use a GUI)
  • Configure your iOS project to use MvxSidebarPresenter

    by adding the following code to a class Setup

    in your iOS project:

    protected override IMvxIosViewPresenter CreatePresenter()
    {
        return new MvxSidebarPresenter((MvxApplicationDelegate)ApplicationDelegate, Window);
    }
    
          

  • Create a view controller that acts like a dropdown menu and decorate it with MvxSidebarPresentationAttribute

    . This controller will act as your menu. You can (or better) associate it with a viewmodel that will handle the navigation portion (when the user selects a menu item). This view controller might look something like this:

    [MvxSidebarPresentation(MvxPanelEnum.Left, MvxPanelHintType.PushPanel, false)]
    public class LeftPanelView : MvxViewController<LeftPanelViewModel>
    {
        ...
    }
    
          

  • To make your homeview act as the root controller, just add MvxSidebarPresentationAttribute

    to the homeview controller and make sure the property is Panel

    set to Center

    , HintType

    set to, ResetRoot

    and ShowPanel

    set to true

    ), for example:

    [MvxSidebarPresentation(MvxPanelEnum.Center, MvxPanelHintType.ResetRoot, true)]
    public class HomeView : MvxViewController<HomeViewModel>
    {
        ...
    }
    
          

  • All child views (open from home type), make sure that you have set MvxSidebarPresentationAttribute

    with the parameter Panel

    set on Center

    , HintType

    on PushPanel

    , and depending on if you want to display the menu button on the child pages, set ShowPanel

    at true

    orfalse

    , for example:

    [MvxSidebarPresentation(MvxPanelEnum.Center, MvxPanelHintType.PushPanel, true)]
    public class ChildView : MvxViewController<ChildViewModel>
    {
        ...
    }
    
          

  • The final step is to set up a view controller for all the other buttons in the menu. They can simply be decorated with an attribute MvxModalPresentationAttribute

    to open them up as a dialog (detailed documentation can be found here ). An example might look something like this:

    [MvxModalPresentation(ModalPresentationStyle = UIModalPresentationStyle.OverFullScreen, ModalTransitionStyle = UIModalTransitionStyle.CrossDissolve)]
    public partial class ModalView : MvxViewController<ModalViewModel>
    {
        ...
    }
    
          

To open different views, you can use the new navigation service in MvvmCross. To do this, simply allow the IoC MvvmCross container to inject an instance into your viewmodel constructor (more information can be found here ):

public class HomeViewModel : MvxViewModel
{
    private readonly IMvxNavigationService _navigationService;

    public HomeViewModel(IMvxNavigationService navigationService)
    {
        _navigationService = navigationService ?? throw new ArgumentNullException(nameof(navigationService));
    }
}

      



EDIT 1: To be able to display an icon as a menu button, you need to implement an interface IMvxSidebarMenu

on the view controller that makes up the menu (see Step 3). When implementing this interface, you can override the default behavior in the menu, and can be found here (which is part of the MvvmCross XamarinSidebar app demo .)

EDIT 2: I mistakenly assumed that you can show the menu button (or its icon) on a child view that is pushed onto the navigation stack. This is not the case, child views that are pushed onto the stack will not show the menu button. In these cases, the property is ShowPanel

completely ignored.

EDIT 3: There is a way to fully implement this circuit. We can customize the glass navigation UI so that we can simulate something like an Android toolbar. This approach works, and basically it requires us to hide the navbar and create our custom toolbar containing the hamburger menu, back button and other buttons and placing it at the top of the child's view. Here is the code required for the close and back buttons:

public override void ViewDidLoad()
        {
            base.ViewDidLoad();
            NavigationController.NavigationBarHidden = true;

            btnClose.TouchUpInside += (object sender, EventArgs e) =>
            {
                NavigationController.NavigationBarHidden = false;
                NavigationController.PopViewController(false);
            };

            btnShowMenu.TouchUpInside += (object sender, EventArgs e) =>
            {
                var sideMenu = Mvx.Resolve<IMvxSidebarViewController>();
                sideMenu?.Open(MvxPanelEnum.Left);
            };
        }

      

+8


source







All Articles