public class App
{
public static Page GetMainPage ()
{
AuditorDB.Model.Extensions.AutoTimestamp = true;
return new NavigationPage (new LoginPage ());
}
}
您可以修改 GetMainPage 方法以返回新的TabbedPaged或您在项目中定义的其他页面
从那以后,您可以添加命令或事件处理程序来执行代码
// to show OtherPage and be able to go back
Navigation.PushAsync(new OtherPage());
// to show AnotherPage and not have a Back button
Navigation.PushModalAsync(new AnotherPage());
// to go back one step on the navigation stack
Navigation.PopAsync();
public class DependencyResolver
{
static IContainer container;
public DependencyResolver(params Module[] modules)
{
var builder = new ContainerBuilder();
if (modules != null)
foreach (var module in modules)
builder.RegisterModule(module);
container = builder.Build();
}
public T Resolve<T>() => container.Resolve<T>();
public object Resolve(Type type) => container.Resolve(type);
}
public partial class App : Application
{
public DependencyResolver DependencyResolver { get; }
// Pass here platform specific dependencies
public App(Module platformIocModule)
{
InitializeComponent();
DependencyResolver = new DependencyResolver(platformIocModule, new IocModule());
MainPage = new WelcomeView();
}
/* The rest of the code ... */
}
public class TypeMapperService
{
public Type MapViewModelToView(Type viewModelType)
{
var viewName = viewModelType.FullName.Replace("Model", string.Empty);
var viewAssemblyName = GetTypeAssemblyName(viewModelType);
var viewTypeName = GenerateTypeName("{0}, {1}", viewName, viewAssemblyName);
return Type.GetType(viewTypeName);
}
public Type MapViewToViewModel(Type viewType)
{
var viewModelName = viewType.FullName.Replace(".Views.", ".ViewModels.");
var viewModelAssemblyName = GetTypeAssemblyName(viewType);
var viewTypeModelName = GenerateTypeName("{0}Model, {1}", viewModelName, viewModelAssemblyName);
return Type.GetType(viewTypeModelName);
}
string GetTypeAssemblyName(Type type) => type.GetTypeInfo().Assembly.FullName;
string GenerateTypeName(string format, string typeName, string assemblyName) =>
string.Format(CultureInfo.InvariantCulture, format, typeName, assemblyName);
}
10 回答
在App类中,您可以将MainPage设置为导航页面并将根页面设置为您的ContentPage:
然后在您的第一个ContentPage调用中:
呼叫:
在App.xaml.cs中创建此方法:
使用 Navigation 属性在Xamarin.forms中的一个页面到另一个页面导航下面的示例代码
使用视图单元格将一个页面导航到另一个页面下面的代码为Xamrian.forms
示例如下
将新页面推入堆栈,然后删除当前页面 . 这导致切换 .
您需要先进入导航页面:
切换内容并不理想,因为您只有一个大页面和一组页面事件,如OnAppearing等 .
如果您的项目已经设置为PCL表单项目(很可能也作为共享表单,但我还没有尝试过),那么有一个类App.cs,如下所示:
您可以修改
GetMainPage
方法以返回新的TabbedPaged或您在项目中定义的其他页面从那以后,您可以添加命令或事件处理程序来执行代码
通过使用PushAsync()方法,您可以推送PopModalAsync(),您可以在导航堆栈中弹出页面 . 在我的下面的代码示例中,我有一个导航页面(根页面),在我完成登录页面后,我会从这个页面推送一个登录页面的内容页面,然后返回到根页面
//为简单起见删除了代码,只显示了pop
XAML页面添加了这个
在CS页面上
似乎这个线程非常受欢迎,如果有另一种方法,那就更难过了 -
ViewModel First Navigation
. 大多数MVVM框架都使用它,但是如果你想了解它是什么,继续阅读 .所有官方Xamarin.Forms文档都演示了一个简单但略微不是MVVM的纯解决方案 . 那是因为
Page
(View)对ViewModel
一无所知,反之亦然 . 以下是此违规行为的一个很好的示例:如果你有一个2页的应用程序,这种方法可能对你有好处 . 但是,如果您正在开发大型企业解决方案,最好采用
ViewModel First Navigation
方法 . 它稍微复杂但更干净的方法允许您在ViewModels
之间导航,而不是在Pages
(视图)之间导航 . 除了明确区分关注点之外的一个优点是,您可以轻松地将参数传递给下一个ViewModel
或在导航后立即执行异步初始化代码 . 现在详细说明 .(我将尝试尽可能简化所有代码示例) .
1.首先,我们需要一个可以注册所有对象并可选择定义其生命周期的地方 . 对于这个问题,我们可以使用IOC容器,您可以自己选择一个 . 在这个例子中,我将使用Autofac(它是速度最快的之一) . 我们可以在
App
中保留对它的引用,以便全局可用(不是一个好主意,但需要简化):2.我们需要一个负责检索特定
ViewModel
的Page
(View)的对象,反之亦然 . 在设置应用程序的根/主页面时,第二种情况可能很有用 . 为此我们应该就一个简单的约定达成一致,即所有ViewModels
应该在ViewModels
目录中,Pages
(视图)应该在Views
目录中 . 换句话说ViewModels
应该位于[MyApp].ViewModels
名称空间和[MyApp].Views
(查看)[MyApp].Views
名称空间中 . 除此之外,我们应该同意WelcomeView
(页面)应该WelcomeViewModel
等 . 以下是映射器的代码示例:3.对于设置根页面的情况,我们需要
ViewModelLocator
来自动设置BindingContext
:4.最后,我们需要一个支持
ViewModel First Navigation
方法的NavigationService
:正如您所看到的那样
BaseViewModel
是所有ViewModels
的抽象基类,您可以在其中定义InitializeAsync
之类的方法,这些方法将在导航后立即执行 . 以下是导航示例:如您所知,这种方法更复杂,更难调试,可能会令人困惑 . 然而,由于大多数MVVM框架都支持开箱即用,因此有许多优点,而且您实际上不需要自己实现它 . 此处演示的代码示例可在github上找到 .
有很多关于
ViewModel First Navigation
方法的好文章,还有一本免费的Enterprise Application Patterns using Xamarin.Forms电子书,它详细解释了这个以及许多其他有趣的主题 .Xamarin.Forms
支持内置多个导航主机:NavigationPage
,下一页幻灯片放入,TabbedPage
,你不喜欢的那个CarouselPage
,允许左右切换到下一页/上一页 .除此之外,所有页面还支持
PushModalAsync()
,它只是在现有页面之上推送新页面 .最后,如果您想确保用户无法返回上一页(使用手势或后退硬件按钮),您可以保持显示相同的
Page
并替换其Content
.替换根页的建议选项也适用,但您必须为每个平台处理不同的方法 .
如果您不想转到上一页,即在授权完成后不让用户返回登录屏幕,那么您可以使用;
如果要启用后退功能,请使用