Как я могу иметь общий элемент управления ProgressCircle, доступный для всех представлений? - PullRequest
0 голосов
/ 15 марта 2019

Я разработчик для Android, пытаюсь освоить разработку UWP и пытаюсь использовать Prism Library и Windows Template Studio , чтобы помочь мне с эталонной функциональностью.

Моя цель - иметь элемент управления ProgressCircle, доступный для всех представлений, чтобы всякий раз, когда я выполняю асинхронный вызов, я мог всплывать ProgressCircle. В попытке сохранить вещи СУХИМ, я не хочу иметь ProgressCircle в каждом представлении. Как мне этого добиться?

Насколько я понимаю, Prism, созданный в Windows Template Studio, имеет представление ShellPage, в котором размещены все другие представления, и имеет собственную viewModel. Это похоже на модель Android / Activity / Fragment. Моя первоначальная идея состояла в том, чтобы поместить ProgressCircle в представление ShellPage, а затем вызвать его из моего дочернего представления (MainPage) при необходимости. Однако я не понял, как вызывать методы viewModel других представлений из дочернего / другого представления / viewModel. Это правильный подход, и если да, то как я могу это сделать?

Моя другая идея - создать сервис приложений Progress, который можно добавить в базовый класс viewModel, но я пока не узнал о сервисах приложений.

1 Ответ

1 голос
/ 27 марта 2019

Хорошо, поэтому я не уверен, что с Prism все по-другому, поскольку я использую шаблон кодирования (я ничего не знаю об этом, но, насколько я мог видеть, это было не так разные). В любом случае страница оболочки, созданная Windows Template Studio, должна выглядеть примерно так:

<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>

Тогда к этому можно обратиться в вашей ShellPage с именем, которое вы дали вашему ProgressRing, но получить доступ к нему из других представлений может быть непросто, так как вам потребуется получить доступ к экземпляру ShellPage непосредственно из них. Одна вещь, которую вы могли бы сделать, это реализовать события для активации и деактивации ProgressRing, которые можно вызывать из любого места в вашем коде, и реализовать обработчики, которые подписались бы на эти события в вашем классе ShellPage.

Надеюсь, это поможет.

...