MAUI-导航

2023-02-08 09:12 Wednesday5952min
CC BY 4.0(除特别声明和转载)

导航时ViewModel的生成

使用QueryProperty特性来处理查询的数据传递以生成一个详情页所需的viewModel

[QueryProperty(nameof(Monkey), "Monkey")]
public partial class MonkeyDetailsViewModel : BaseViewModel
{
    public MonkeyDetailsViewModel()
    {
    }

    [ObservableProperty]
    Monkey monkey;
}

可以使用相同的机制传递一个完整的对象

var person = new Person { Name="James" };
await Shell.Current.GoToAsync("DetailsPage", new Dictionary<string, object>
{
    { "person", person }
});

然后在页面或视图模型上创建该属性。

[QueryProperty(nameof(Person), "person")]  
public partial class DetailsPage : ContentPage  
{  
    Person person;  
    public Person Person  
    {  
        get => person;  
        set => person = value;  
    }  
}

在这里导航时,Person 会自动为我们序列化和反序列化。

从视图中获取数据

使用RelayCommand特性:

[RelayCommand]
async Task GoToDetails(Monkey monkey)
{
    if (monkey == null)
    return;

    await Shell.Current.GoToAsync(nameof(DetailsPage), true, new Dictionary<string, object>
    {
        {"Monkey", monkey }
    });
}

上述代码中的GoToDetails方法会生成GoToDetailsCommand,可绑定到视图中使用,如下:

<CollectionView.ItemTemplate>
    <DataTemplate x:DataType="model:Monkey">
        <Grid Padding="10">
            <Frame HeightRequest="125" Style="{StaticResource CardView}">
                <!-- Add the Gesture Recognizer-->
                <Frame.GestureRecognizers>
                    <TapGestureRecognizer 
                            Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:MonkeysViewModel}}, Path=GoToDetailsCommand}"
                            CommandParameter="{Binding .}"/>
                </Frame.GestureRecognizers>
                <Grid Padding="0" ColumnDefinitions="125,*">
                    <Image
                        Aspect="AspectFill"
                        HeightRequest="125"
                        Source="{Binding Image}"
                        WidthRequest="125" />
                    <VerticalStackLayout
                        Grid.Column="1"
                        VerticalOptions="Center"
                        Padding="10">
                        <Label Style="{StaticResource LargeLabel}" Text="{Binding Name}" />
                        <Label Style="{StaticResource MediumLabel}" Text="{Binding Location}" />
                    </VerticalStackLayout>
                </Grid>
            </Frame>
        </Grid>
    </DataTemplate>
</CollectionView.ItemTemplate>

注册路由

有了详细信息页面,需要注册它以进行路由。 这是在 Shell 路由系统和 .NET MAUI 依赖项服务中完成的。打开后面的AppShell.xaml.cs代码,在InitializeComponent()下加入如下代码:

Routing.RegisterRoute(nameof(DetailsPage), typeof(DetailsPage));

完成关于DetailsPage的路由的注册。

MauiProgram.cs中将视图模型和页面都添加为Transient,这样每次导航到时都会创建一个新的页面和视图模型:

    builder.Services.AddTransient<MonkeyDetailsViewModel>();  
    builder.Services.AddTransient<DetailsPage>();  

将视图模型注入到我们的 DetailsPage 视图中。 在 DetailsPage.xaml.cs中注入viewModel的代码演示:

 public DetailsPage(MonkeyDetailsViewModel viewModel)  
    {  
    	InitializeComponent();  
    	BindingContext = viewModel;  
    }
BuyMeACola