带 Flipview 的图片库

Image Gallery with Flipview

I want to create a gallery image on the first page contains a thumbnail for that category and when thumbnail is selected, it will open the image and description of the selected image in flipview (can be swipe to the right and to为前后图像选择缩略图时的左侧)。应用到flipview时遇到困难

代码: 主页 XAML

<GridView
    x:Name="itemGridView"
    AutomationProperties.AutomationId="ItemGridView"
    AutomationProperties.Name="Grouped Items"
    Grid.RowSpan="3"
    Padding="116,137,40,46"
    ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
    SelectionMode="None"
    IsSwipeEnabled="false"
    IsItemClickEnabled="True"
    ItemClick="ItemView_ItemClick" Background="#FF6996D1" >
    <GridView.ItemTemplate>
        <DataTemplate>
            <Grid HorizontalAlignment="Left" Width="240" Height="180">
                <Border>
                    <Image Source="{Binding ImagePath}" Stretch="Uniform" AutomationProperties.Name="{Binding Title}"/>
                </Border>
            </Grid>
        </DataTemplate>
    </GridView.ItemTemplate>
    <GridView.ItemsPanel>
        <ItemsPanelTemplate>
            <ItemsWrapGrid GroupPadding="0,0,70,0"/>
        </ItemsPanelTemplate>
    </GridView.ItemsPanel>
</GridView>

主页:

public MainPage()
{
    this.InitializeComponent();
    Gallery();
}

private async void Gallery()
{
    var sampleDataGroups = await DataItemSource.GetGroupsAsync();
    this.DefaultViewModel["Groups"] = sampleDataGroups;
}

void ItemView_ItemClick(object sender, ItemClickEventArgs e)
{
    // Navigate to the appropriate destination page, configuring the new page
    // by passing required information as a navigation parameter
    var itemId = ((SampleDataItem)e.ClickedItem).UniqueId;
    this.Frame.Navigate(typeof(ItemDetailPage), itemId);
}

ItemDetailPage XAML:

<Grid Grid.Row="1" x:Name="contentRegion" Background="#FF6996D1">
    <Image Source="{Binding ImagePath}" HorizontalAlignment="Left" Height="559" Margin="84,20,0,49" VerticalAlignment="Center" Width="732"/>
    <ScrollViewer x:Name="myScroll" VerticalScrollBarVisibility="Auto" Margin="852,60,50,91" VerticalScrollMode="Auto" HorizontalScrollBarVisibility="Auto">
        <TextBlock Text="{Binding Description}" TextWrapping="Wrap" Height="2210" Width="425" FontSize="27" TextAlignment="Justify" />
    </ScrollViewer>
</Grid>

ItemDetailPage 代码:

public ItemDetailPage()
{
    this.InitializeComponent();
    this.navigationHelper = new NavigationHelper(this);
    this.navigationHelper.LoadState += navigationHelper_LoadState;
}

private async void navigationHelper_LoadState(object sender, LoadStateEventArgs e)
{
    // TODO: Create an appropriate data model for your problem domain to replace the sample data
    var item = await DataItemSource.GetItemAsync((String)e.NavigationParameter);
    this.DefaultViewModel["Item"] = item;
}

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    navigationHelper.OnNavigatedTo(e);
}

protected override void OnNavigatedFrom(NavigationEventArgs e)
{
    navigationHelper.OnNavigatedFrom(e);
}

如何在 ItemDetailPage 上应用 flipview?

注意: 有关更多代码详细信息,您可以查看 sample

要在 ItemDetailPage 上应用 flipview,我们可以在 "contentRegion" 下添加 FlipView 并将 ImageScrollViewer 设置为 FlipView 的 [=18] =] 如下所示:

<Grid x:Name="contentRegion" Grid.Row="1" Background="#FF6996D1">
    <FlipView ItemsSource="{Binding Group.Items}" SelectedItem="{Binding Item, Mode=TwoWay}">
        <FlipView.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Image Width="732"
                           Height="559"
                           Margin="84,20,0,49"
                           HorizontalAlignment="Left"
                           VerticalAlignment="Center"
                           Source="{Binding ImagePath}" />
                    <ScrollViewer x:Name="myScroll"
                                  Margin="852,60,50,91"
                                  HorizontalScrollBarVisibility="Auto"
                                  VerticalScrollBarVisibility="Auto"
                                  VerticalScrollMode="Auto">
                        <TextBlock Width="425"
                                   Height="2210"
                                   FontSize="27"
                                   Text="{Binding Description}"
                                   TextAlignment="Justify"
                                   TextWrapping="Wrap" />
                    </ScrollViewer>
                </Grid>
            </DataTemplate>
        </FlipView.ItemTemplate>
    </FlipView>
</Grid>

并且在代码隐藏中,设置数据源如下:

private async void navigationHelper_LoadState(object sender, LoadStateEventArgs e)
{
    // TODO: Create an appropriate data model for your problem domain to replace the sample data
    var item = await DataItemSource.GetItemAsync((String)e.NavigationParameter);
    var group = await DataItemSource.GetGroupByItemAsync(item);
    this.DefaultViewModel["Group"] = group;
    this.DefaultViewModel["Item"] = item;
}

这里我在DataItemSource中添加了一个GetGroupByItemAsync(SampleDataItem item)方法,可以根据item检索分组

public static async Task<SampleDataGroup> GetGroupByItemAsync(SampleDataItem item)
{
    await _DataItemSource.GetSampleDataAsync();
    // Simple linear search is acceptable for small data sets
    var matches = _DataItemSource.Groups.Where(group => group.Items.Contains(item));
    if (matches.Count() == 1) return matches.First();
    return null;
}

除此之外,我们还需要从根Grid中删除DataContext="{Binding Item}"并放入<Grid Background="#FF6996D1" DataContext="{Binding Item}">.

在此之后,FlipView 应该可以工作了。但是这里有一个奇怪的行为,如果我们 select 第二张或第三张图片,翻转视图中的前一张图片将不会显示如下

我们正在调查这个问题。作为解决方法,我们可以通过更改其 ItemsPanel 来禁用 FlipView 的虚拟化,例如:

<FlipView.ItemsPanel>
    <ItemsPanelTemplate>
        <StackPanel Orientation="Horizontal" />
    </ItemsPanelTemplate>
</FlipView.ItemsPanel>

ItemDetailPage 的完整 XAML 代码可能喜欢:

<Page x:Class="ImageGalerry.ItemDetailPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:common="using:ImageGalerry.Common"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:data="using:ImageGalerry.Data"
      xmlns:local="using:ImageGalerry"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      DataContext="{Binding DefaultViewModel,
                            RelativeSource={RelativeSource Self}}"
      mc:Ignorable="d">

    <Grid d:DataContext="{Binding Groups[0].Items[0], Source={d:DesignData Source=/DataModel/DataItem.json, Type=data:DataItemSource}}" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

        <Grid.RowDefinitions>
            <RowDefinition Height="140" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <!--  Back button and page title  -->
        <Grid Background="#FF6996D1" DataContext="{Binding Item}">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="1366" />
            </Grid.ColumnDefinitions>
            <Button x:Name="backButton"
                    Margin="39,59,0,0"
                    VerticalAlignment="Top"
                    AutomationProperties.AutomationId="BackButton"
                    AutomationProperties.ItemType="Navigation Button"
                    AutomationProperties.Name="Back"
                    Command="{Binding NavigationHelper.GoBackCommand,
                                      ElementName=pageRoot}"
                    Style="{StaticResource NavigationBackButtonNormalStyle}" />
            <TextBlock x:Name="pageTitle"
                       Margin="120,40,30,40"
                       VerticalAlignment="Top"
                       IsHitTestVisible="false"
                       Style="{StaticResource HeaderTextBlockStyle}"
                       Text="{Binding Title}"
                       TextWrapping="NoWrap" />
            <!--<MediaElement x:Name="mediaplayer" Source="images/ost.mp3" AudioCategory="BackgroundCapableMedia" />
            <Button x:Name="PlayButton" Content="Stop" Click="PlayButton_Click" Margin="1274,72,0,30" />-->
        </Grid>

        <Grid x:Name="contentRegion" Grid.Row="1" Background="#FF6996D1">
            <FlipView ItemsSource="{Binding Group.Items}" SelectedItem="{Binding Item, Mode=TwoWay}">
                <FlipView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal" />
                    </ItemsPanelTemplate>
                </FlipView.ItemsPanel>
                <FlipView.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <Image Width="732"
                                   Height="559"
                                   Margin="84,20,0,49"
                                   HorizontalAlignment="Left"
                                   VerticalAlignment="Center"
                                   Source="{Binding ImagePath}" />
                            <ScrollViewer x:Name="myScroll"
                                          Margin="852,60,50,91"
                                          HorizontalScrollBarVisibility="Auto"
                                          VerticalScrollBarVisibility="Auto"
                                          VerticalScrollMode="Auto">
                                <TextBlock Width="425"
                                           Height="2210"
                                           FontSize="27"
                                           Text="{Binding Description}"
                                           TextAlignment="Justify"
                                           TextWrapping="Wrap" />
                            </ScrollViewer>
                        </Grid>
                    </DataTemplate>
                </FlipView.ItemTemplate>
            </FlipView>
        </Grid>
    </Grid>
</Page>

请注意,为 FlipView 禁用 UI 虚拟化可能会对性能产生负面影响,尤其是当有大量图像时。如果你的图片比较多,可以尝试使用增量加载和数据虚拟化。