Шаблон содержимого панели SplitView с MVVM - PullRequest
0 голосов
/ 22 июня 2019

Мне нужна помощь, чтобы обернуть мозг вокруг концепций MVVM. Я должен сказать, что до сих пор это было трудно изучить, потому что некоторая информация в Интернете противоречит друг другу. Поэтому, если у кого-то есть надежный источник информации / учебник, который может меня куда-то достать, я бы очень признателен.

Однако на данный момент мне нужна помощь в выяснении, как я могу закрыть панель SplitView в приложении UWP с помощью MVVM из Content of the Pane. У меня есть ShellView, который размещает SplitView, а его панель содержит ContentPresenter, содержимое которого может быть динамически изменено на один из двух шаблонов. Свойства Bindng находятся в ViewModel, как и свойство IsSubscriptionPaneOpen.

ShellView.xaml (Страница):

<SplitView
          Name="sv"
          DisplayMode="Overlay"
          OpenPaneLength="280"
          IsPaneOpen="{Binding IsSubscriptionsPaneOpen, Mode=TwoWay, UpdateSourceTrigger=Default}">
          <SplitView.Pane>
          <ContentPresenter
              Content="{Binding PaneContent, Mode=OneWay, UpdateSourceTrigger=Default}"
              ContentTransitions="{StaticResource NavigationTransitions}"/>
          </SplitView.Pane>
          <Grid>
              <Frame
                  x:Name="RootFrame"
                  ContentTransitions="{StaticResource NavigationTransitions}"/>
          </Grid>
</SplitView>

Затем следует одно из представлений шаблонов, которое необходимо создать в свойстве PaneContent. Я делаю это в ShellViewModel, как показано ниже:

private SubscriptionsView SubsPaneView { get; set; }

if (SubsPaneView == null) SubsPaneView = new SubscriptionsView();
PaneContent = SubsPaneView;

SubscriptionView.xaml (UserControl):

<UserControl.Resources>
        <ViewModels:SubscriptionsViewModel x:Key="SubsVM"/>

        <DataTemplate x:Key="UserSubscriptionsDataTemplate"
                      x:DataType="model:SubscriptionsItem">
            <UserControl>
                <Grid
                    Name="rootPanel">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="Auto"/>
                    </Grid.ColumnDefinitions>
                    <Grid.Background>
                        <ImageBrush 
                            ImageSource="{Binding ChannelCoverUrl, Mode=OneWay, UpdateSourceTrigger=Default}"
                            Opacity="0.4"/>
                    </Grid.Background>
                    <Ellipse
                        Name="imageBorder"
                        Grid.Column="0"
                        Height="44"
                        Width="44"
                        Stroke="{StaticResource SystemControlBackgroundAccentBrush}"
                        StrokeThickness="1"
                        VerticalAlignment="Center">
                        <Ellipse.Fill>
                            <ImageBrush>
                                <ImageBrush.ImageSource>
                                    <BitmapImage
                                        UriSource="{Binding ImageUrl, Mode=OneWay}"/>
                                </ImageBrush.ImageSource>
                            </ImageBrush>
                        </Ellipse.Fill>
                    </Ellipse>
                    <TextBlock
                        Name="title"
                        Grid.Column="1"
                        Style="{StaticResource BodyTextBlockStyle}"
                        Text="{Binding Title, Mode=OneWay, UpdateSourceTrigger=Default}"
                        MaxLines="2"
                        TextTrimming="CharacterEllipsis"
                        Margin="4,0"
                        VerticalAlignment="Center"
                        ToolTipService.ToolTip="{Binding Title, Mode=OneWay}"/>
                    <Border
                        Name="newContent"
                        Grid.Column="2"
                        Background="{StaticResource SystemControlBackgroundAccentBrush}"
                        CornerRadius="100"
                        Height="36"
                        Width="36"
                        VerticalAlignment="Center"
                        Visibility="{Binding NewItemCount, Mode=OneWay, UpdateSourceTrigger=Default, Converter={StaticResource NumberToVisibleConverter}}">
                        <ToolTipService.ToolTip>
                            <TextBlock>
                            <Run Text="Updates:"/>
                            <Run Text="{Binding NewItemCount, Mode=OneWay, UpdateSourceTrigger=Default}"/>
                            </TextBlock>
                        </ToolTipService.ToolTip>
                        <TextBlock
                            Text="{Binding NewItemCount, Mode=OneWay, UpdateSourceTrigger=Default}"
                            FontSize="12"
                            VerticalAlignment="Center"
                            TextAlignment="Center"/>
                    </Border>
                    <AppBarButton
                        Name="subsRemoveBtn"
                        Grid.Column="3"
                        Height="40"
                        Width="40"
                        Style="{StaticResource SquareAppBarButtonStyle}"
                        Command="{Binding OpenUnsubscribeFlyout, Mode=OneWay, UpdateSourceTrigger=Default}"
                        VerticalAlignment="Center">
                        <AppBarButton.Icon>
                            <FontIcon
                                Glyph="&#xE107;"
                                Margin="0,-4,0,0"/>
                        </AppBarButton.Icon>
                        <FlyoutBase.AttachedFlyout>
                            <Flyout helpers:FlyoutHelper.IsOpen="{Binding IsFlyoutOpen, Mode=TwoWay, UpdateSourceTrigger=Default}"
                                    helpers:FlyoutHelper.Parent="{Binding ElementName=subsRemoveBtn}">
                                <Button
                                    Content="Unsubscribe"
                                    Command="{Binding RemoveSubscription, Mode=OneWay, UpdateSourceTrigger=Default}"
                                    CommandParameter="{Binding ID, Mode=OneWay, UpdateSourceTrigger=Default}"/>
                            </Flyout>
                        </FlyoutBase.AttachedFlyout>
                        <ToolTipService.ToolTip>
                            <TextBlock
                                TextWrapping="Wrap">
                                <Run Text="Unsubscribe"/>
                                <Run Text="{Binding Title, Mode=OneWay, UpdateSourceTrigger=Default}"/>
                            </TextBlock>
                        </ToolTipService.ToolTip>
                    </AppBarButton>
                </Grid>
            </UserControl>
        </DataTemplate>
    </UserControl.Resources>

<ListView
            Name="subscriptionsList"
            Grid.Row="1"
            helpers:ItemClickCommand.Command="{Binding ViewChannelCommand}"
            ScrollViewer.VerticalScrollBarVisibility="Hidden"
            ItemTemplate="{StaticResource UserSubscriptionsDataTemplate}"
            ItemsSource="{Binding SubscriptionsList, Mode=OneWay, UpdateSourceTrigger=Default}"
            SelectedItem="{Binding SelectedSubscription, Mode=TwoWay, UpdateSourceTrigger=Default}"/>

Сначала я закрывал панель с помощью экземпляра ShellViewModel, доступного только для чтения, но я не думаю, что это чисто MVVM, и поэтому я смотрю на то, как сделать его чисто MVVM. Цель состоит в том, чтобы использовать команду Click в subscriptionList, чтобы закрыть панель.

public CustomICommand<SubscriptionsItem> ViewChannelCommand { get; private set; }

ViewChannelCommand = new CustomICommand<SubscriptionsItem>(ViewSubscriptionChannel, CanViewSubscriptionChannel);

private void ViewSubscriptionChannel(SubscriptionsItem channel)
{
    CommandsService.ViewUserChannelForChannelID(channel.ChannelID, false);
    //ShellViewModel.Instance?.IsSubscriptionsPaneOpen = false;
}

Теперь я не вижу способа закрыть панель с помощью ItemTemplate объекта ListView. Я полагаю, что это возможно через инъекцию зависимостей, потому что я уже использую ту же самую вещь для закрытия всплывающих окон, но я не знаю, как реализовать это здесь, потому что нет доступной документации. Кто-нибудь может помочь?

Edit: Я использую ниже класс для ListView itemclick через шаблон MVVM.

public static class ItemClickCommand
    {
        public static readonly DependencyProperty CommandProperty =
            DependencyProperty.RegisterAttached("Command", typeof(ICommand),
            typeof(ItemClickCommand), new PropertyMetadata(null, OnCommandPropertyChanged));

        public static void SetCommand(DependencyObject d, ICommand value)
        {
            d.SetValue(CommandProperty, value);
        }

        public static ICommand GetCommand(DependencyObject d)
        {
            return (ICommand)d.GetValue(CommandProperty);
        }

        private static void OnCommandPropertyChanged(DependencyObject d,
            DependencyPropertyChangedEventArgs e)
        {
            var control = d as ListViewBase;
            if (control != null)
                control.ItemClick += OnItemClick;
        }

        private static void OnItemClick(object sender, ItemClickEventArgs e)
        {
            var control = sender as ListViewBase;
            var command = GetCommand(control);

            if (command != null && command.CanExecute(e.ClickedItem))
                command.Execute(e.ClickedItem);
        }
    }

1 Ответ

0 голосов
/ 28 июня 2019

Здесь разумно добавить еще одно свойство зависимости в класс ItemClickCommand:

...
        public static readonly DependencyProperty IsPanelOpenCommandProperty =
            DependencyProperty.RegisterAttached("IsPanelOpenCommand", typeof(ICommand),
            typeof(ItemClickCommand), null);

        public static void SetIsPaneOpenCommand(DependencyObject d, ICommand value)
        {
            d.SetValue(IsPanelOpenCommandProperty, value);
        }

        public static ICommand GetIsPaneOpenCommand(DependencyObject d)
        {
            return (ICommand)d.GetValue(IsPanelOpenCommandProperty);
        }

        // in item click insert the following
        var paneCommand = GetIsPaneOpenCommand(control);
        if (paneCommand != null)
           paneCommand.Execute();
....
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...