Irregular behavior - XAML / UWP Community Toolkit

2019-03-02 04:40发布

问题:

Problem : I am using UWP Community Toolkit Scale animation and it works as expected for most of the images in the GridView, but for some the image goes out of bounds . (Please see the image below)

I have detected that the issue happens when the image width is more than 2x (2 times) the height of the image. That is when the image is very wide.


Code

I am using a user control as data template Xaml :

<!-- Grid View  -->
<GridView x:Name="gridView" SelectionChanged="gridView_SelectionChanged">
   <GridView.ItemTemplate>
      <DataTemplate>
           <local:GridViewMenu/>
      </DataTemplate>
   </GridView.ItemTemplate>
</GridView>

<!-- GridViewMenu User Control markup -->
<Grid>
  <StackPanel>
    <Image Source="{Binding webformatURL}" Stretch="UniformToFill" PointerEntered="image_PointerEntered" PointerExited="image_PointerExited"/>
  </StackPanel>
</Grid>

C# Code :

        private void image_PointerEntered(object sender, PointerRoutedEventArgs e)
        {
            Image img = sender as Image;            

            img.Scale(centerX: (float)(grid.ActualWidth / 2),
                        centerY: 100,
                        scaleX: 1.2f,
                        scaleY: 1.2f,
                        duration: 500, delay: 0).StartAsync();
        }

        private void image_PointerExited(object sender, PointerRoutedEventArgs e)
        {
            Image img = sender as Image;

            img.Scale(centerX: (float)(grid.ActualWidth / 2),
                        centerY: 100,
                        scaleX: 1f,
                        scaleY: 1f,
                        duration: 500, delay: 0).StartAsync();
        }

Result (Top left image is not scaling as expected, that is, it is going out of bounds)

How can I solve this issue ?

回答1:

The scale animation of UWP Community Toolkit package actually use the CompositeTransform class for scaling. According to the description of Transforms and layout section:

Because layout comes first, you'll sometimes get unexpected results if you transform elements that are in a Grid cell or similar layout container that allocates space during layout. The transformed element may appear truncated or obscured because it's trying to draw into an area that didn't calculate the post-transform dimensions when dividing space within its parent container.

So that the parts overflow the bound that being truncated are unexpected. In another words, the image goes out is the transform expected. The current way you are using to meet your requirements is not reliable. If you change width-height ratio of GridViewMenu to 1.0 , you may find more images that width-height ratio larger than 1.0 will go out.

For a solution inside GridView, you could consider to use the ScrollViewer to zoom in the image instead, which can ensure the image is limited in a fixed area. For example:

<Grid x:Name="grid">
   <ScrollViewer
       x:Name="currentscroll"
       HorizontalScrollBarVisibility="Hidden"
       VerticalScrollBarVisibility="Hidden">
       <Image
           x:Name="myImage"
           Width="300"
           Height="180"
           PointerEntered="image_PointerEntered"
           PointerExited="image_PointerExited"
           Source="{Binding webformatURL}"
           Stretch="UniformToFill"> 
       </Image>
   </ScrollViewer>
</Grid>

Code behind:

private  void image_PointerEntered(object sender, PointerRoutedEventArgs e)
{ 
    currentscroll.ChangeView(0, 0, 1.2f ); 
}

private  void image_PointerExited(object sender, PointerRoutedEventArgs e)
{ 
    currentscroll.ChangeView(0, 0, 1.0f); 
}


回答2:

You can try to use clipping:

 <Grid>
   <StackPanel>
      <Image Source="{Binding webformatURL}" Stretch="UniformToFill" 
                PointerEntered="image_PointerEntered" 
                PointerExited="image_PointerExited">
          <Image.Clip>
              <RectangleGeometry Rect="0,0,300,150" />
          </Image.Clip>
      </Image>
   </StackPanel>
 </Grid> 

300 and 150 would be the width and height of the grid item.

Otherwise it looks like a bug in the UWP Community Toolkit, it would be best to report it as an issue on GitHub.