Search code examples
uwpuwp-xamlflipviewwindows-community-toolkit

Flipview UI freeze while fast swiping


I am developing an UWP Application which shows Images and Videos in a FlipView control. The Flipview control is put aside an AdaptiveGridView from the UWP Community Toolkit which shows all available Images/Videos for the FlipView. The FlipView and the AdaptiveGridView share the same ItemsSource and SelectedItem. So when i select one photo in the AdaptiveGridView the FlipView shows that item and the other way around. The photo/video collection can be very large (>500 images).

 <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.ColumnDefinitions>
        <ColumnDefinition MinWidth="165" Width="0.3*" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="0.7*" MinWidth="400" />
    </Grid.ColumnDefinitions>
    <controls:AdaptiveGridView x:Name="FeedItemGridView" Grid.Column="0"
                               ItemsSource="{x:Bind FeedItems}"
                               SelectedItem="{x:Bind SelectedFeedItem, Mode=TwoWay}"
                               OneRowModeEnabled="False"
                               ItemHeight="150"
                               DesiredWidth="150"
                               SelectionMode="Single"
                               ItemTemplate="{StaticResource ThumbImageTemplate}" />
    <controls:GridSplitter Grid.Column="1" Width="14" ResizeBehavior="BasedOnAlignment"
                           ResizeDirection="Auto" 
                           FontSize="13" Background="{ThemeResource ApplicationForegroundThemeBrush}">
        <controls:GridSplitter.Element>
            <TextBlock HorizontalAlignment="Center"
                       IsHitTestVisible="False"
                       VerticalAlignment="Center"
                       Text="&#xE784;"
                       Foreground="{ThemeResource SystemControlBackgroundAccentBrush}"
                       FontFamily="Segoe MDL2 Assets" />
        </controls:GridSplitter.Element>
    </controls:GridSplitter>
    <FlipView Grid.Column="2"  ItemsSource="{x:Bind FeedItems}" x:Name="FlipView" ItemTemplate="{StaticResource FeedViewerFlipViewTemplate}"
              SelectedItem="{x:Bind SelectedFeedItem, Mode=TwoWay}"
            >
    </FlipView>
</Grid>

This works very good and smooth.

The DataTemplate for the FlipView is the following.

 <DataTemplate x:Key="FeedViewerFlipViewTemplate">
    <ScrollViewer HorizontalScrollMode="Disabled">
        <StackPanel>
            <ScrollViewer ZoomMode="Enabled" MinZoomFactor="1" HorizontalScrollBarVisibility="Hidden"
                          VerticalScrollBarVisibility="Hidden" HorizontalScrollMode="Enabled"
                          VerticalScrollMode="Enabled">
                <Border BorderThickness="2" BorderBrush="{ThemeResource AppBarBorderThemeBrush}">
                    <Grid x:Name="MediaGrid">
                        <Image
                            Stretch="Uniform"
                            Source="{Binding FeedItem.ImageSource}"
                            HorizontalAlignment="Center" VerticalAlignment="Center"
                            Visibility="{Binding FeedItem.IsVideo, Converter={StaticResource BooleanToVisibilityConverterInverse}}" />
                        <MediaPlayerElement
                            Visibility="{Binding ElementName=FeedItemGridView, Path=SelectedItem.FeedItem.IsVideo, Converter={StaticResource BoolToVisConverter}}"
                            AreTransportControlsEnabled="True"
                            Source="{Binding ElementName=FeedItemGridView, Path=SelectedItem.FeedItem.ImageSource, Converter={StaticResource MediaSourceFromUriConverter}, UpdateSourceTrigger=Explicit}"
                            PosterSource="{Binding ElementName=FeedItemGridView, Path=SelectedItem.FeedItem.ThumbSource}"
                            Stretch="Uniform">
                            <MediaPlayerElement.TransportControls>
                                <MediaTransportControls IsCompact="False"
                                                        IsVolumeButtonVisible="{Binding ElementName=FeedItemGridView, Path=SelectedItem.FeedItem.Audio}" />
                            </MediaPlayerElement.TransportControls>
                        </MediaPlayerElement>
                    </Grid>
                </Border>
            </ScrollViewer>
            <ItemsControl x:Name="TagsList" ItemsSource="{Binding Tags}"
                          Margin="{StaticResource SmallLeftRightMargin}"
                          ItemTemplate="{StaticResource TagTemplate}" HorizontalContentAlignment="Stretch">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <controls1:CustomWrapPanel />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemContainerStyle>
                    <Style TargetType="ContentPresenter">
                        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
                        <Setter Property="VerticalContentAlignment" Value="Stretch" />
                    </Style>
                </ItemsControl.ItemContainerStyle>
            </ItemsControl>
            <StackPanel Orientation="Horizontal" Margin="{StaticResource MediumAllMargin}"
                        x:Name="CommentCountPanel">
                <SymbolIcon Margin="{StaticResource MediumLeftMargin}" Symbol="Comment" />
                <TextBlock Margin="{StaticResource MediumLeftMargin}" Text="{Binding CommentViewModels.Count}" />
                <TextBlock Margin="{StaticResource MediumLeftMargin}" x:Uid="Comments" />
            </StackPanel>
            <ItemsControl x:Name="CommentsList"
                          ItemsSource="{Binding CommentViewModels}" ItemTemplate="{StaticResource CommentTemplate}">
                <ItemsControl.ItemContainerStyle>
                    <Style TargetType="ContentPresenter">
                        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
                        <Setter Property="VerticalContentAlignment" Value="Stretch" />
                    </Style>
                </ItemsControl.ItemContainerStyle>
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <VirtualizingStackPanel />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
        </StackPanel>
    </ScrollViewer>
</DataTemplate>

The DataTemplate for the FlipView visualize the Photo/Video and some more information. When i remove the the ItemTemplate from the CommentLists i can swipe without any problems through the Flipview or go through the items from the AdaptiveGridView and the UI respond without lags. But when i set ItemTemplate for the CommentsList the UI freezes when i swipe very fast.

The DataTemplate for the CommentsList is the following

<DataTemplate x:Key="CommentTemplate">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <ItemsControl Grid.Column="0" ItemsSource="{Binding ParentDepthList}" HorizontalContentAlignment="Stretch"
                      VerticalContentAlignment="Stretch">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <VirtualizingStackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Rectangle Stroke="{ThemeResource SystemControlForegroundBaseHighBrush}"
                               VerticalAlignment="Stretch" Opacity="0.2" Width="1" StrokeThickness="1"
                               StrokeDashArray="1,2" StrokeDashCap="Round" Margin="{StaticResource BigRightMargin}" />
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
        <Border BorderThickness="0 0 0 1 " Grid.Column="1" HorizontalAlignment="Stretch"
                VerticalAlignment="Stretch"
                BorderBrush="{ThemeResource SystemControlForegroundBaseHighBrush}"
                Margin="{StaticResource MediumLeftMargin}">
            <StackPanel>
                <controls:MarkdownTextBlock Text="{Binding Comment.Content}" VerticalContentAlignment="Center"
                                            HorizontalContentAlignment="Center" VerticalAlignment="Center"
                                            micro:Message.Attach="[Event LinkClicked] = [Action OpenLink($eventArgs)]"
                                            Margin="{StaticResource SmallLeftMargin}"
                                            LinkForeground="{ThemeResource SystemControlForegroundBaseHighBrush}" />
                <StackPanel Orientation="Horizontal" Margin="{StaticResource MediumAllMargin}">
                    <HyperlinkButton
                        micro:Message.Attach="[Event LinkClicked] = [Action OpenLink($eventArgs)]"
                        NavigateUri="{Binding Comment.Name, Converter={StaticResource UserTextConverter}}"
                        Content="{Binding Comment.Name}" />
                    <TextBlock Margin="10 0 0 0" VerticalAlignment="Center">-</TextBlock>
                    <TextBlock VerticalAlignment="Center" Text="{Binding Comment.Created}"
                               Margin="{StaticResource MediumLeftMargin}" />
                </StackPanel>
            </StackPanel>
        </Border>
    </Grid>

Does anybody know why the UI freeze when i set the DataTemplate for the CommentsList?

Thanks in advance.


Solution

  • While you are using a VirtualizingStackPanel, the items will not be virtualizied because the content is placed within a ScrollViewer. As far as the VirtualizingStackPanel is concerned, it has plenty of room to render every item.

    I would recommend that you put comments in a separate panel from your FlipView. Maybe put it to the side of your FlipView and adjust the layout depending on the size of the window.