This commit is contained in:
Martijn van Dijk 2018-03-28 15:55:01 +02:00
Родитель 12ad522641
Коммит c29f32a7e1
3 изменённых файлов: 114 добавлений и 192 удалений

Просмотреть файл

@ -4,11 +4,12 @@ title: Navigation
category: Fundamentals
order: 2
---
MvvmCross uses `ViewModel first navigation`. Meaning that we navigate from ViewModel to ViewModel and not from View to View. In MvvmCross the ViewModel will lookup its corresponding View. By doing so we don't have to write platform specific navigation and we can manage everything from within our core.
# MvvmCross 5.x and higher navigation
# Introducing the MvxNavigationService
MvvmCross 5 introduces a new NavigationService! The new navigation enables you to inject it into your ViewModels, which makes it more testable, and gives you the ability to implement your own navigation! Other main features are that it is fully async and type safe.
The navigation enables you to inject it into your ViewModels, which makes it more testable, and gives you the ability to implement your own navigation! Other main features are that it is fully async and type safe.
For more details see [#1634](https://github.com/MvvmCross/MvvmCross/issues/1634)
The following Api is available to use:
@ -48,7 +49,7 @@ public interface IMvxNavigationService
Task<bool> Close(IMvxViewModel viewModel);
Task<bool> Close<TResult>(IMvxViewModelResult<TResult> viewModel, TResult result);
bool ChangePresentation(MvxPresentationHint hint);
Task<bool> ChangePresentation(MvxPresentationHint hint);
}
```

Просмотреть файл

@ -0,0 +1,98 @@
---
layout: documentation
title: Xamarin.Forms View Presenter
category: Platforms
---
## View Presenter Overview
On Forms every platform has it's own presenter that inherits from the native platform presenter. This enables us to navigate between native and Xamarin.Forms views. On top of that we have the `MvxFormsPagePresenter` which handles all the comon logic for Forms related navigation.
The default presenter supports every navigation pattern that Xamarin.Forms supports itself:
- Tabs
- MasterDetail
- Childs
- Etc
Also if your app needs another kind of presentation mode, you can easily extend it!
## Presentation Attributes
The presenter uses a set of `PresentationAttributes` to define how a view will be displayed. The existing attributes are:
### MvxPagePresentationAttribute
This is the base class for the other Forms presentation attributes and cannot be used directly.
| Name | Type | Description |
| ---- | ---- | ----------- |
| HostViewModelType | `Type` | Can optionally be set to make sure the Page has the correct Host type. |
| WrapInNavigationPage | `bool` | When you want the Page to be shown in a new NavigationPage or when the current Stack already is a NavigationPage push it inside there. This is true by default. |
| NoHistory | `bool` | Clears out the other pages from the navigation stack. False by default. |
| Animated | `bool` | Indicates if the navigation should be animated. This is true by default. |
| Title | `string` | The optional title of the Page |
| Icon | `string` | The optional Icon of a Page |
### MvxCarouselPagePresentationAttribute
Used to navigate forward to one or multipel pages in a Carousel.
| Name | Type | Description |
| ---- | ---- | ----------- |
| Position | `CarouselPosition` | Use this to set the position of the Page. It can either be the `Root` to host Pages, or as a `Carousel` to be a Page inside the carousel. |
### MvxContentPagePresentationAttribute
This is the standard Page attribute.
### MvxMasterDetailPagePresentationAttribute
| Name | Type | Description |
| ---- | ---- | ----------- |
| Position | `MasterDetailPosition` | Use this to set the position of the Page. It can either be the `Root` to host Pages, `Master` to be a Page inside the Master, or `Detail` to be as the content of the Page. |
### MvxModalPresentationAttribute
Will show the Page as a Modal.
### MvxNavigationPagePresentationAttribute
Used to indicate that this is a NavigationPage.
### MvxTabbedPagePresentationAttribute
| Name | Type | Description |
| ---- | ---- | ----------- |
| Position | `TabbedPosition` | Use this to set the position of the Page. It can either be the `Root` to host Pages, or as a `Tab` to be a Page inside the TabbedPage. |
## Views without attributes: Default values
- If a view class has no attribute over it, the presenter will check the type and try to create the correct attribute for it:
- CarouselPage -> `MvxCarouselPagePresentationAttribute`
- ContentPage -> `MvxContentPagePresentationAttribute`
- MasterDetailPage -> `MvxMasterDetailPagePresentationAttribute`
- NavigationPage -> `MvxNavigationPagePresentationAttribute`
- TabbedPage -> `MvxTabbedPagePresentationAttribute`
## Override a presentation attribute at runtime
To override a presentation attribute at runtime you can implement the `IMvxOverridePresentationAttribute` in your view and determine the presentation attribute in the `PresentationAttribute` method like this:
```c#
public MvxBasePresentationAttribute PresentationAttribute(MvxViewModelRequest request)
{
return new MvxContentPagePresentationAttribute()
{
};
}
```
As you can see in the code snippet, you will be able to make your choice using a `MvxViewModelRequest`. This object will contain the `PresentationValues` dictionary alongside other properties.
If you return `null` from the `PresentationAttribute` method, the ViewPresenter will fallback to the attribute used to decorate the view. If the view is not decorated with any presentation attribute, then it will use the default attribute instead.
__Hint:__ Be aware that `this.ViewModel` property will be null during `PresentationAttribute`. If you want to have the ViewModel instance available, you need to use the `MvxNavigationService` and cast the `request` parameter to `MvxViewModelInstanceRequest`.

Просмотреть файл

@ -1,206 +1,29 @@
---
layout: documentation
title: Xamarin.Forms Tutorial
title: MvvmCross for Xamarin.Forms
category: Platforms
---
With the introduction of MvvmCross 5.0 we have full support for Xamarin Forms!
MvvmCross tries to align Forms as much as possible with the native Xamarin features. You'll be able to use almost any of them, but some implementations have Forms specific implementations.
# Tutorial
# Startup
Let's take a look at setting up a project
You need to inherit the Forms variant of the startup point for the platform. For example: `MvxFormsAppdelegate`.
MvvmCross has some very helpful Nuget packages to get you started. In this case we will use the StarterPack Nuget to install the basic files and the MvvmCross.Forms Nuget to get us connected to Forms. Another great way is to use a Visual Studio extension like XabluCross for MvvmCross. In this guide Im going to use Visual Studio for Mac to develop the sample App. You should be able to do the same using Visual Studio 2017, but things might just look slightly different.
# Setup
Note: this tutorial is using MvvmCross 5.0.7. Using other versions may not work!
Use the Forms specific Setup for each platform, and we will load up the neccesary bases. You can do this by extending from example `MvxFormsAndroidSetup`.
- Open up Visual Studio and start creating a New Solution in the File menu in the Menu.
- In the Multi-platform section select Blank Forms App.
- Enter the name for your new project, for this sample we will call it: MvxForms
- As Target platforms we leave the default selected ones, Android and iOS.
- For shared code we pick Portable Class Library. More information on that is available in the MvvmCross documentation.
- In this we will use XAML for our layouts so leave that on default.
- In the next page we leave the Project name and solution name to MvxForms. I would advice to create a .gitignore file if you are using Git. Press Create to finish.
- In MvvmCross it is common to name the shared code project ".Core". Change the name from MvxForms to MvxForms.Core.
- Open the Core, Android and iOS projects, double click Packages and add the MvvmCross.StarterPack nuget and the MvvmCross.Forms nuget.
- Remove the ToDo-MvvmCross and Views folders in the Android and iOS projects.
- Change the App.cs name from:
# Presenters
```c#
public class App : MvvmCross.Core.ViewModels.MvxApplication
```
On Forms every platform has it's own presenter that inherits from the native platform presenter. This enables us to navigate between native and Xamarin.Forms views. On top of that we have the `MvxFormsPagePresenter` which handles all the comon logic for Forms related navigation.
To:
```c#
public class CoreApp : MvvmCross.Core.ViewModels.MvxApplication
```
We do this because otherwise the Forms.App class conflicts with the MvvmCross.App class.
- Edit the App.xaml file from:
```c#
<FormsApplication xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MvxForms.Core.App"
</FormsApplication>
```
To:
```c#
<d:MvxFormsApplication xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MvxForms.Core.App"
xmlns:d="clr-namespace:MvvmCross.Forms.Core;assembly=MvvmCross.Forms">
</d:MvxFormsApplication>
```
Do the same for App.xaml.cs
```c#
public partial class App : FormsApplication
```
To:
```c#
public partial class App : MvxFormsApplication
```
- Remove the line 'MainPage = MvxFormsPage();' from App.xaml.cs.
- In the Setup.cs class of Android and iOS, change:
```c#
protected override IMvxApplication CreateApp()
{
return new Core.App();
}
```
To:
```c#
protected override IMvxApplication CreateApp()
{
return new Core.CoreApp();
}
protected override MvvmCross.Forms.Core.MvxFormsApplication CreateFormsApplication()
{
return new App();
}
```
- Also change the base class of the Android setup from MvxAndroidSetup to MvxFormsAndroidSetup. Do the same on iOS from MvxIosSetup to MvxFormsIosSetup.
- Note, if you get the error: No resource found that matches the given name (at icon with value @mipmap/icon). Go to SplashScreen.cs and change Icon = “@mipmap/icon” to Icon = “@drawable/icon”.
- On Android in your Activity replace theOnCreate method with:
```c#
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(bundle);
}
```
On iOS replace your AppDelegate code with:
```c#
public partial class AppDelegate : MvxFormsApplicationDelegate
{
public override UIWindow Window { get; set; }
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
Window = new UIWindow(UIScreen.MainScreen.Bounds);
var setup = new Setup(this, Window);
setup.Initialize();
var startup = Mvx.Resolve<IMvxAppStart>();
startup.Start();
LoadApplication(setup.FormsApplication);
Window.MakeKeyAndVisible();
return true;
}
}
```
- The last step is to make your Xamarin.Forms page extend the MvxContentPage. You can either use a generic or name based convention to make MvvmCross recognize it. In MvxFormsPage.xaml.cs change:
```c#
public partial class MvxFormsPage : ContentPage
```
To:
```c#
public partial class MvxFormsPage : MvxContentPage<MainViewModel>
```
- You need to change the XAML page attached to it as well:
```c#
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MvxForms.Core">
```
To:
```c#
<d:MvxContentPage x:TypeArguments="viewModels:MainViewModel"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MvxForms.Core"
x:Class="MvxForms.Core.MvxFormsPage"
xmlns:viewModels="clr-namespace:MvxForms.Core.ViewModels;assembly=MvxForms.Core"
xmlns:d="clr-namespace:MvvmCross.Forms.Core;assembly=MvvmCross.Forms">
```
- Note, if you are using a SplashScreen on Android you need to add:
```c#
protected override void TriggerFirstNavigate()
{
StartActivity(typeof(MainActivity));
base.TriggerFirstNavigate();
}
```
Otherwise your Forms Activity wouldn't run and you'll stuck on the SplashScreen.
## Fire up the App and enjoy!
The result of this tutorial is available at: https://github.com/martijn00/MvxForms
## Windows UWP
Modify Windows project's MainPage.xaml.cs ctor. in the following way:
```c#
public MainPage()
{
InitializeComponent();
SupportedOrientations = SupportedPageOrientation.PortraitOrLandscape;
var presenter = Mvx.Resolve<IMvxFormsViewPresenter>() as MvxFormsWindowsUWPPagePresenter;
LoadApplication(FormsApplication);
}
```
If you use secondary assemblies for your custom control and renderers, since MvvmCross 6.0 you should also return them from the `GetViewAssemblies` method override, as the view assemblies are passed in to the Xamarin.Forms initialization so that the framework is able to find them in Release mode with .NET Native compilation.
For more information about the Forms presenter see: [Xamarin.Forms view presenter](\xamarin-forms-view-presenter.html)
# Bindings
You can use the MvvmCross binding syntax just like you would do in a native Xamarin project. For more information see the [Bindings](https://www.mvvmcross.com/documentation/fundamentals/data-binding) documentation.
There are some specific Forms bindings but in general you can use any binding that you would in Xamarin native.
# MasterDetail support
# Views
Use the MasterDetail presenters to add support for it to your app.
Every Forms view has a `Mvx` version that handles setting up MvvmCross things like ViewModels. To use this simply add `Mvx` in front of a type. For example: `MvxContentPage`