C# 根据导航参数在页面上显示不同的内容

C# 根据导航参数在页面上显示不同的内容,c#,xaml,uwp,C#,Xaml,Uwp,我想做一本烹饪书,我有一个关于食谱和装订的课程,我在一页中展示它们。当我点击一个菜谱时,我想导航到“菜谱页面”,根据我来自的链接,文本、列表等会有所不同 我已经做了recipePage,只有当我用我自己输入的相同数据点击第一个spaggeti配方时,它才会起作用。是否有可能像我上面所说的那样有一个页面并显示不同的数据 这是XAML绑定部分,我将用spaggeti介绍这些食谱 <Grid Margin="20,20,0,0"> <GridView ItemsSource=

我想做一本烹饪书,我有一个关于食谱和装订的课程,我在一页中展示它们。当我点击一个菜谱时,我想导航到“菜谱页面”,根据我来自的链接,文本、列表等会有所不同

我已经做了recipePage,只有当我用我自己输入的相同数据点击第一个spaggeti配方时,它才会起作用。是否有可能像我上面所说的那样有一个页面并显示不同的数据

这是XAML绑定部分,我将用spaggeti介绍这些食谱

<Grid Margin="20,20,0,0">
    <GridView ItemsSource="{x:Bind Categories}" 
              IsItemClickEnabled="True" 
              ItemClick="GridView_ItemClick">
        <GridView.ItemTemplate >
            <DataTemplate x:DataType="data:SpaggetiRecipe">
                <Grid   Margin="30,30,30,30" MaxWidth="230"  MaxHeight="230" MinHeight="200" MinWidth="200">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*"/>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <Image Width="160" Height="160" Source="{x:Bind SpaggetiPhoto}" Grid.Row="0"/>
                    <TextBlock  Text="{x:Bind RecipeName}" Style="{StaticResource Texts}" TextWrapping="WrapWholeWords" Grid.Row="1" Foreground="DarkBlue" FontWeight="SemiBold"/>
                </Grid>
            </DataTemplate>
        </GridView.ItemTemplate>
    </GridView>
</Grid>

这是C部分

私有列表类别;
公共SpaggetiPage()
{
this.InitializeComponent();
Categories=SpaggetiRecipeManager.GetSpaggetiRecipe();
}
私有void GridView\u ItemClick(对象发送者,ItemClickEventArgs e)
{
var spaggetiRecipe=(spaggetiRecipe)e.ClickedItem;
if(spaggetiRecipe.RecipeId==1)
{
框架导航(类型(配方));
}
}
}
您可以参考官方文档中的“钻取页面”场景来实现自己的功能

这里的关键点是使用
Frame.Navigate(TypeName,Object)方法
Frame.Navigate(TypeName,Object,NavigationTransitionInfo)方法
而不是
Frame.Navigate(TypeName)方法
。您可以发送
SpaggetiRecipe
SpaggetiRecipe
的属性,如
SpaggetiRecipe.RecipeId
,作为导航参数。例如:

Frame.Navigate(typeof(Recipe), spaggetiRecipe);

使用基本类型(如
SpaggetRecipeId.RecipeId
)更好,因为它支持使用
GetNavigationState
进行参数序列化,并避免了由于框架导航堆栈中包含对参数的引用而导致的过多内存使用。有关更多信息,请参阅中的备注部分

然后在目标页面的
on navigated to
方法中,您可以使用
e.Parameter
获取导航参数,并使用它获取需要在此页面中使用的数据

在官方示例中,导航参数是一个字符串,它本身被用作数据。在
Recipe
页面中,您可以使用
e.Parameter
获取
spaggetRecipeId.RecipeId
,并使用
RecipeId
获取要在文本、列表等中使用的数据。例如,您可以定义一个
Recipe
类来存储数据,以及一个
GetRecipe
方法,该方法使用
RecipeId
作为参数来初始化数据。在XAML中,您可以像在“recipePage”中那样绑定到它

Recipe
类可能喜欢:

public class Recipe
{
    public string RecipeName { get; set; }
    public List<T> RecipeList { get; set; }
    ...
}
public Recipe GetRecipe(int id)
{
    Recipe recipe = new Recipe();
    //set the data based on the id, here I use switch for example, you may get data for database or some other please
    switch (id)
    {
        case 1:
            recipe =...;
            break;

        case 2:
             recipe =...;
            break;

        ...
    }
    return recipe;
}
在此之后,您可以使用
GetRecipe
获取不同的数据

public Recipe RecipeData { get; set; }

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    if (e.Parameter is int)
    {
        RecipeData = GetRecipe((int)e.Parameter);
    }
    else
    {
        //Something Wrong
    }

    base.OnNavigatedTo(e);
}
然后在XAML中,使用bind来显示数据,如:

<StackPanel>
    <TextBlock Text="{x:Bind RecipeData.RecipeName}" />
    <ListView ItemsSource="{x:Bind RecipeData.RecipeList}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <!--DataTemplate to show RecipeData.RecipeList-->
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</StackPanel>

public Recipe RecipeData { get; set; }

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    if (e.Parameter is int)
    {
        RecipeData = GetRecipe((int)e.Parameter);
    }
    else
    {
        //Something Wrong
    }

    base.OnNavigatedTo(e);
}
<StackPanel>
    <TextBlock Text="{x:Bind RecipeData.RecipeName}" />
    <ListView ItemsSource="{x:Bind RecipeData.RecipeList}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <!--DataTemplate to show RecipeData.RecipeList-->
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</StackPanel>