问题
I with to implement two types of navigation for my app, sidebar navigation and parent-child navigation at the same time. My app starts with hamburger (sidebar) menu.
First item in sidebar menu should perform reset of the navigation stack and open home view. Home view controller should start a root stack navigation so every button on the home view should open a new view, button on a new view should open another view etc.
Every other item in sidebar menu should open a new view as a dialog.
I'm using MvvmCross 5.x, and there is no sample compatible with 5.x version. Is there anyone who can point me to a usable sample?
回答1:
First of I assume you are trying to implement this for iOS. In case of Android you could simply use the Navigation Drawer.
The sample on iOS is not yet converted to MvvmCross 5.x (I will start doing so a.s.a.p.), however this should be trivial. Let me try to walk you through it:
- Make sure you add the MvvmCross iOS Support package to your iOS project:
Install-Package MvvmCross.iOS.Support -Version 5.0.2
(or use the GUI) Configure your iOS project to use the
MvxSidebarPresenter
by adding the following code to theSetup
class in your iOS project:protected override IMvxIosViewPresenter CreatePresenter() { return new MvxSidebarPresenter((MvxApplicationDelegate)ApplicationDelegate, Window); }
Create a view controller which acts as you flyout menu and decorate it with the
MvxSidebarPresentationAttribute
. This view controller will act as your menu. You can (or better should) link it to a view model which will handle the navigation part (when the user selects a menu item). This view controller could look something like this:[MvxSidebarPresentation(MvxPanelEnum.Left, MvxPanelHintType.PushPanel, false)] public class LeftPanelView : MvxViewController<LeftPanelViewModel> { ... }
To make sure your home view act as a root controller simply add the
MvxSidebarPresentationAttribute
to the home view controller and make sure the propertyPanel
is set toCenter
,HintType
is set toResetRoot
andShowPanel
is set totrue
), like so:[MvxSidebarPresentation(MvxPanelEnum.Center, MvxPanelHintType.ResetRoot, true)] public class HomeView : MvxViewController<HomeViewModel> { ... }
For all child views (opened from the home view) make sure you set the
MvxSidebarPresentationAttribute
with the propertyPanel
set toCenter
,HintType
set toPushPanel
and depending if you want to display the menu button on the child pages set the, like so:ShowPanel
totrue
orfalse
[MvxSidebarPresentation(MvxPanelEnum.Center, MvxPanelHintType.PushPanel, true)] public class ChildView : MvxViewController<ChildViewModel> { ... }
The last step is to setup the view controller for all other buttons in the menu. These can simply be decorated with the
MvxModalPresentationAttribute
attribute to open them as a dialog (detailed documentation can be found here). An example could look something like this:[MvxModalPresentation(ModalPresentationStyle = UIModalPresentationStyle.OverFullScreen, ModalTransitionStyle = UIModalTransitionStyle.CrossDissolve)] public partial class ModalView : MvxViewController<ModalViewModel> { ... }
To open the different views you can make use of the new navigation service in MvvmCross. To do so simply allow the MvvmCross IoC container to inject an instance into your view models constructor (more details 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 show an icon on as menu button, you'll need to implement the IMvxSidebarMenu
interface on the view controller that makes up the menu (see step 3). By implementing this interface you can override the default behaviour of the menu, and example can be found here (which is part of the demo MvvmCross XamarinSidebar application).
EDIT 2:
I have mistakenly suggested that you can show the menu (or it's icon) button on a child view which is pushed on the navigation stack. This is not the case, child views that are pushed on the stack will not show the menu button. In these cases the ShowPanel
property is ignored completely.
EDIT 3: There is a way to accomplish that pattern entirely. We can customize stack navigation UI so we can mimic something like Android toolbar. This approach works and it basically requires us to make navigation bar hidden and create our custom toolbar that has hamburger menu, back button and other buttons and put it in the upper part of the child view. Here is the code needed for 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);
};
}
来源:https://stackoverflow.com/questions/44497462/mvvmcross-sidebar-navigation-for-mvvmcross-5-x