具有MVVM的SplitView的窗格内容模板

时间:2019-06-22 07:21:53

标签: c# xaml mvvm uwp

我需要一些帮助使我的头脑围绕MVVM的概念。我必须说,到目前为止,由于互联网上的某些信息彼此矛盾,因此很难学习它。因此,如果有人能获得可靠的信息/教程资源,并且可以将我带到某个地方,我将不胜感激。

但是,到目前为止,我需要帮助来弄清楚如何在窗格内容中借助MVVM在UWP应用中关闭SplitView窗格。我有一个ShellView,它托管SplitView,而其窗格则托管ContentPresenter,其内容可以动态更改为两个模板之一。 Bindng属性位于ViewModel中,IsSubscriptionsPaneOpen属性也位于中。

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的只读实例关闭Pane的,但是我不认为它是纯粹的MVVM,这就是为什么我在研究如何使其纯粹是MVVM。 目标是使用subscriptionsList的Click命令关闭窗格。

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

现在,我看不到通过ListView的ItemTemplate关闭窗格的方法。我相信通过依赖注入可能是可能的,因为我已经使用相同的方法关闭了Flyout,但是由于没有可用的文档,我不知道如何在这里实现它。有人可以帮忙吗?

编辑: 我正在使用下面的类通过MVVM模式进行ListView itemclick。

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 :(得分:0)

此处合理的做法是在上面的array_keys类中添加另一个依赖项属性:

ItemClickCommand