Мне нужна помощь, чтобы обернуть мозг вокруг концепций 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=""
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);
}
}