我是一名Android开发人员,试图学习UWP开发,并尝试使用Prism Library和Windows Template Studio来帮助我实现样板功能。
我的目标是拥有一个可由所有视图访问的ProgressCircle控件,这样,每当我执行异步调用时,我都可以弹出ProgressCircle。为了使事情保持干燥,我不想在每个视图中都有一个ProgressCircle。我该如何实现?
据我了解,Windows Template Studio构建的(Prism)具有一个ShellPage视图,该视图包含其中的所有其他视图,并且具有自己的viewModel。这似乎有点类似于Android的“活动/片段”模型。我最初的想法是将ProgressCircle放在ShellPage视图中,然后在需要时从我的子视图(MainPage)中调用它。但是我还没有弄清楚如何从子视图/其他视图/ viewModel中调用另一个视图viewModel方法。这是正确的方法吗?如果可以,我该怎么做?
我的另一个想法是创建一个可以添加到viewModel基类中的Progress应用程序服务,但是我尚未了解应用程序服务。
答案 0 :(得分:1)
好吧,所以我不确定Prism是否有什么不同,因为我正在使用代码行为模式(我对此一无所知,但据我所知,不是吗不同)。无论如何,Windows Template Studio创建的Shell Page看起来应该类似于:
<Page
x:Class="MyProject.Views.ShellPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="using:Microsoft.Xaml.Interactivity"
xmlns:behaviors="using:armada_vpn.Behaviors"
xmlns:winui="using:Microsoft.UI.Xaml.Controls"
xmlns:helpers="using:MyProject.Helpers"
xmlns:views="using:MyProject.Views"
Loaded="OnLoaded"
mc:Ignorable="d" Background="Black">
<winui:NavigationView
x:Name="navigationView"
IsBackButtonVisible="Visible"
IsBackEnabled="{x:Bind IsBackEnabled, Mode=OneWay}"
SelectedItem="{x:Bind Selected, Mode=OneWay}"
ItemInvoked="OnItemInvoked"
IsSettingsVisible="False"
Background="White" RequestedTheme="Light"
OpenPaneLength="200">
<winui:NavigationView.MenuItems>
<!--
TODO WTS: Change the symbols for each item as appropriate for your app
More on Segoe UI Symbol icons: https://docs.microsoft.com/windows/uwp/style/segoe-ui-symbol-font
Or to use an IconElement instead of a Symbol see https://github.com/Microsoft/WindowsTemplateStudio/blob/master/docs/projectTypes/navigationpane.md
Edit String/en-US/Resources.resw: Add a menu item title for each page
-->
<winui:NavigationViewItem x:Uid="Shell_Main" Icon="Home" helpers:NavHelper.NavigateTo="views:MainPage" />
</winui:NavigationView.MenuItems>
<i:Interaction.Behaviors>
<behaviors:NavigationViewHeaderBehavior
x:Name="navigationViewHeaderBehavior"
DefaultHeader="{x:Bind ViewModel.Selected.Content, Mode=OneWay}">
<behaviors:NavigationViewHeaderBehavior.DefaultHeaderTemplate>
<DataTemplate>
<Grid>
<TextBlock
Text="{Binding}"
Style="{ThemeResource TitleTextBlockStyle}"
Margin="{StaticResource SmallLeftRightMargin}" />
</Grid>
</DataTemplate>
</behaviors:NavigationViewHeaderBehavior.DefaultHeaderTemplate>
</behaviors:NavigationViewHeaderBehavior>
<ic:EventTriggerBehavior EventName="ItemInvoked">
<ic:InvokeCommandAction Command="{x:Bind ViewModel.ItemInvokedCommand}" />
</ic:EventTriggerBehavior>
</i:Interaction.Behaviors>
<Grid> #This here is important for you
<Frame x:Name="shellFrame"/>
</Grid>
</winui:NavigationView>
</Page>
在XAML页面中指定的网格区域是您的不同视图的显示位置,因为ShellPage控制此框架中显示的内容。
无论如何,您要做的是将进度环添加到该框架的顶部(并具有透明背景)。为此,您可以为两个元素都指定一个ZIndex(具有最高ZIndex的元素将显示在顶部:
<Grid>
<ProgressRing x:Name="ProgressRing" Canvas.ZIndex="2" Background="Transparent"/>
<Frame x:Name="shellFrame" Canvas.ZIndex="1"/>
</Grid>
或者,您可以简单地将ProgressRing定义为此处的最后一个元素(因为,未指定任何ZIndex,渲染顺序是从上到下):
<Grid>
<Frame x:Name="shellFrame"/>
<ProgressRing x:Name="ProgressRing" Background="Transparent"/>
</Grid>
然后,可以使用您给您的ProgressRing的名称在ShellPage中访问它,但是从其他视图访问它可能很棘手,因为您需要直接从它们访问ShellPage实例。您可以做的一件事是实现用于激活和停用可从代码中任何地方引发的ProgressRing的事件,并实现可在ShellPage类中订阅这些事件的处理程序。
希望有帮助。