Xamarin.form页面导航在mvvm中
我正在开发xamarin.form跨平台应用程序,我希望在按钮点击时从一个页面导航到另一个页面。 因为我不能做Navigation.PushAsync(new Page2());
在ViewModel中,因为它只能在Code-Behid文件中使用。 请建议任何方式这样做?
这是我的观点:
这是我的ViewModel:
public class LocalAccountViewModel : INotifyPropertyChanged { public LocalAccountViewModel() { this.ContinueBtnClicked = new Command(GotoPage2); } public void GotoPage2() { ///// } public ICommand ContinueBtnClicked { protected set; get; } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanges([CallerMemberName] string PropertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName)); } }
一种方法是您可以通过VM构造函数传递导航。 由于页面inheritance自VisualElement
,因此它们直接inheritanceNavigation
属性。
代码隐藏文件:
public class SignIn : ContentPage { public SignIn(){ InitializeComponent(); // Note the VM constructor takes now a INavigation parameter BindingContext = new LocalAccountViewModel(Navigation); } }
然后在您的VM中,添加一个INavigation
属性并更改构造函数以接受INavigation
。 然后,您可以使用此属性进行导航:
public class LocalAccountViewModel : INotifyPropertyChanged { public INavigation Navigation { get; set;} public LocalAccountViewModel(INavigation navigation) { this.Navigation = navigation; this.ContinueBtnClicked = new Command(async () => await GotoPage2()); } public async Task GotoPage2() { ///// await Navigation.PushAsync(new Page2()); } ...
请注意您应修复的代码问题: GoToPage2()
方法必须设置为async
并返回Task
类型。 此外,该命令将执行异步操作调用。 这是因为你必须异步进行页面导航!
希望能帮助到你!
一个简单的方法是
this.ContinueBtnClicked = new Command(async()=>{ await Application.Current.MainPage.Navigation.PushAsync(new Page2()); });
从您的VM
public Command RegisterCommand { get { return new Command(async () => { await Application.Current.MainPage.Navigation.PushAsync(new RegisterNewUser()); }); } }
我调查了这个,这实际上取决于你想要如何处理你的导航。 您是希望视图模型处理导航还是想要您的视图? 我发现最简单的方法是让我的视图处理我的导航,以便我可以选择针对不同的情况或应用程序使用不同的导航格式。 在这种情况下,不要使用命令绑定模型,只需使用按钮单击事件并将新页面添加到后面的代码中的导航堆栈中。
将按钮更改为:
在您的代码中,实现该方法并在那里进行导航。
public void Button_Clicked(object sender, EventArgs e) { Navigation.PushAsync(new Page2()); }
如果您正在寻找基于视图模型的导航,我相信有一种方法可以使用MvvmCross,但我不熟悉该工具。
我的方法基于原则每个模型只能导航到基于VM上下文的应用程序位置:
在ViewModel中,我声明INavigationHandler是这样的:
public class ItemsViewModel : ViewModelBase { public INavigationHandler NavigationHandler { private get; set; } // some VM code here where in some place i'm invoking RelayCommand ItemSelectedCommand => new RelayCommand ((itemID) => { NavigationHandler.NavigateToItemDetail(itemID); }); public interface INavigationHandler { void NavigateToItemDetail(int itemID); } }
并为ViewModel分配代码隐藏类作为INavigationHandler:
public class ItemsPage : ContentPage, ItemsViewModel.INavigationHandler { ItemsViewModel viewModel; public ItemsPage() { viewModel = Container.Default.Get(); viewModel.NavigationHandler = this; } public async void NavigateToItemDetail(int itemID) { await Navigation.PushAsync(new ItemDetailPage(itemID)); } }