我正在处理xamarin。表单跨平台应用程序,我想通过单击按钮从一个页面导航到另一个页面。由于我无法在ViewModel中执行Navigation.PushAsync(new Page2());
,因为它只能在Code-Behid文件中执行。请建议任何方法来执行此操作?
以下是我的观点:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Calculator.Views.SignIn"
xmlns:ViewModels="clr-namespace:Calculator.ViewModels;assembly=Calculator">
<ContentPage.BindingContext>
<ViewModels:LocalAccountViewModel/>
</ContentPage.BindingContext>
<ContentPage.Content>
<StackLayout>
<Button Command="{Binding ContinueBtnClicked}" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
以下是我的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));
}
}
9条答案
按热度按时间798qvoo81#
一种方法是通过VM构造函数传递Navigation。由于页面继承自
VisualElement
,因此它们直接继承Navigation
属性。代码隐藏文件:
然后,在VM中添加一个
INavigation
属性,并将构造函数更改为接受INavigation
。请注意您的程式码中有一个您应该修正的问题:
GoToPage2()
方法必须设置为async
并返回Task
类型。此外,该命令将执行异步操作调用。这是因为您必须异步进行页面导航!希望能有所帮助!
qmb5sa222#
一个简单的方法是
nfzehxib3#
从虚拟机
9o685dep4#
通过VM构造函数传递INavigation确实是一个很好的解决方案,但是如果您有深度嵌套的VM体系结构,它也会非常耗费代码。
用可从任何视图模型访问的单例来 Package INavigation是一种替代方法:
导航分派程序单例:
在App.xaml.cs中初始化:
在任何ViewModel中使用:
3qpi33ja5#
我研究了这个问题,这实际上取决于您希望如何处理导航。您希望视图模型处理导航还是希望视图处理导航。我发现让视图处理导航是最简单的,这样我就可以为不同的情况或应用程序选择不同的导航格式。在这种情况下,与其使用命令绑定模型,只需使用按钮单击事件并将新页面添加到后面代码中的导航堆栈。
将按钮更改为类似以下内容:
在您的程式码后置中,实作方法并在那里进行巡览。
如果您正在寻找基于视图模型的导航,我相信有一种方法可以使用MvvmCross来实现,但我对该工具并不熟悉。
ac1kyiln6#
我的方法基于每个视图只能导航到基于VM上下文的应用程序位置的原则:
在ViewModel中,我声明如下INavigationHandler接口:
并将代码隐藏类指定为ViewModel的INavigationHandler:
y1aodyip7#
我决定添加两种方法将Page示例传递给视图模型,您可以在以后使用视图模型进行导航、显示警报、关闭页面等操作。
1.如果可以使用命令参数传递它
在视图模型中:
视图模型构造器
viewmodel中的某个位置
XAML语言
集管
用法
2.已开始在我的viewmodel基类中使用此方法
视图模型
...
...
XAML语言
我们开始吧
子视图模型
现在,在子视图模型周围,我们可以使用类似Parent.DisplayAlert或Parent.Navigation.PushAsync等页面,我们甚至可以使用Parent.PopAsync()从视图模型关闭页面;
vs3odd8k8#
当我转向Xamarin开发时,我在这几天里绞尽脑汁,遇到了同样的障碍。
所以我的答案是把页面的Type放在Model中,但如果你选择这样做的话,不要限制View或ViewModel与它一起工作。这使系统保持灵活性,因为它不会通过视图或代码隐藏中的硬连线来束缚Navigation,因此它更容易移植。您可以跨项目重用您的模型,并且只需要设置在其他项目中出现这种情况时将导航到的Page的类型。
为此,我生成了一个IValueConverter
和ICommand
现在,模型可能有一个可分配的页面类型,因此它可以改变,页面可以在不同的设备类型(例如手机,手表,Android,iOS)之间不同。
这是一个在Xaml中使用它的例子。
为了完整性起见,App.xaml中定义的资源
P.S.虽然命令模式通常应该为一个操作使用一个示例,但在本例中,我知道在所有控件中重用同一个示例是非常安全的,因为它是针对可穿戴设备的,所以我希望保持比正常情况更轻的东西,因此在App.xaml中定义了NavigationCommand的单个示例。
jbose2ul9#
我认为导航应该在View中而不是ViewModel中
这是我的解决方案
记录页.xaml
记录页. xaml.cs
记录页面视图模型.cs