XAML Master/ ;使用MVVM的模板页面

XAML Master/ ;使用MVVM的模板页面,xaml,mvvm,uwp,Xaml,Mvvm,Uwp,是否有方法在XAML中创建母版/模板页(用于UWP应用程序) 我试图解决的问题: 我有一个应用程序,有许多类似的网站,其中只有内容略有变化,但没有按钮和布局。例如: <Page DataContext="{Binding WebpageViewModel, Source={StaticResource Locator}}"> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush

是否有方法在XAML中创建母版/模板页(用于UWP应用程序)

我试图解决的问题:
我有一个应用程序,有许多类似的网站,其中只有内容略有变化,但没有按钮和布局。例如:

<Page
    DataContext="{Binding WebpageViewModel, Source={StaticResource Locator}}">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <TextBlock Grid.Row="0" Text="Edit Webpage" Style="{StaticResource BigTexBlock}" />
            <ScrollViewer  Style="{StaticResource ContentScrollViewer}" Grid.Row="1" VerticalScrollMode="Enabled">
                <StackPanel Margin="10,0">
                    <webpage:EditWebpage DataContext="{Binding }" />
                </StackPanel>
            </ScrollViewer>
        </Grid>
    </Grid>

    <Page.BottomAppBar>
        <CommandBar>
            <CommandBar.PrimaryCommands>
                <!-- more buttons -->
                <AppBarButton IsCompact="True" Command="{Binding SaveEntryCommand}" Icon="Save" Label="Save" />
            </CommandBar.PrimaryCommands>
        </CommandBar>
    </Page.BottomAppBar>
</Page>

。您可以定义母版/模板页,并在子模板中覆盖部分母版/模板页

对我来说重要的是

  • 我不会破坏MVVM模式
  • 我不想在一个“主”XAML中隐藏/显示UserControls,因为不同实体的数量可能会变得相当大
  • 我希望在用户看到预期动画的页面之间进行导航,并且它不会破坏我已有的分离视图代码

    • 没有其他技术(如MVC)所拥有的母版页或模板机制。但是你可以使用框架和导航来做你想要做的事情

      您可以按照当前的方式定义页面。页面上的所有固定元素都在布局中。现在,不要对特定的编辑UI使用UserControl,而是将其替换为框架

      <StackPanel Margin="10,0">
          <Frame Name="EditFrame" DataContext="{Binding }" />
      </StackPanel>
      
      
      
      现在,当您导航到主编辑页面时,还要在框架中传递所需视图的类型。然后,在OnNavigatedTo覆盖主页面时,可以将框架导航到视图类型作为参数

      您还可以使用EditFrame在多个编辑页面之间翻页,就像您有一个带有“下一步”和“上一步”按钮的向导UI,而无需离开主页


      您可以在OnNavigatedTo方法中执行此操作,也可以修改NavigationService以处理此行为。

      我已使用建议的方法解决了此问题

      我的导航服务

      //get the current frame
      var frame = (Frame)Window.Current.Content;
      //navigate to the generic AddEntry page
      frame.Navigate(typeof(AddEntryPage), new NavigationParameter() { /* set props needed */ });
      
      我的xaml(我的“母版页”)现在看起来是这样的(使用
      框架
      now):


      github上的完整项目:

      UWP社区工具包中有一个控件。也许它可以帮助你。我最初希望避免在XAML页面后面使用代码,但似乎没有其他方法,我可能最终会做一些类似于你所建议的事情。感谢您提供有关导航到
的提示,您不必在代码隐藏中执行此操作。您使用的是什么MVVM库/框架?可以通过扩展应用程序的导航服务来实现这一点。您有吗?我使用的是
mvvmlight
库,带有
INavigationService
的自定义实现。有了代码隐藏,我的意思是覆盖
OnNavigatedTo
方法,我习惯于每个视图模型只有一个页面,页面中根本没有代码。如果是这样,您可以扩展自定义导航服务,允许您通过目标帧(按名称)以及导航到的页面。然后NavigationService可以找到框架并调用其导航方法到特定的编辑子页面。这有意义吗?那么你就不必在代码隐藏文件中有代码了。我已经用你建议的方法解决了这个问题,谢谢!我使用了
OnNavigatedEvent
来避免
NavigationService
的复杂性(我有多个模板页)
<Page
    x:Class="Famoser.Bookmarked.Presentation.Universal.Pages.Entry.Webpage.AddEntryPage"
    mc:Ignorable="d"
    d:DataContext="{Binding WebpageViewModel, Source={StaticResource Locator}}">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <TextBlock x:Name="Title" Grid.Row="0" Text="Add "/>
        <ScrollViewer Grid.Row="1">
            <StackPanel Margin="10,0">
                <Frame x:Name="EntryFrame" />
            </StackPanel>
        </ScrollViewer>
    </Grid>

    <Page.BottomAppBar>
        <CommandBar>
            <CommandBar.PrimaryCommands>
                <!-- more app buttons -->
                <AppBarButton IsCompact="True" Command="{Binding SaveEntryCommand}" Icon="Save" Label="Save" />
            </CommandBar.PrimaryCommands>
        </CommandBar>
    </Page.BottomAppBar>
</Page>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    if (e.Parameter is NavigationParameter pm)
    {
        DataContext = SimpleIoc.Default.GetInstance(pm.ViewModelType);
        Title.Text = "Add " + pm.Name;
        EntryFrame.Navigate(pm.EditFrameType);
    }
}