Search code examples
c#scalethumbnailsuwp-xamlwindows-community-toolkit

uwp random sized thumbnails make look adaptiveGridView ugly


In my app I am retrieving thumbnails of only the video files. and I am using AdaptiveGridview of uwp community toolkit with some other file properties to show on the UI.

Problem:

  1. Some files return null thumbnail so I have to fill their BitmapImage with StoreLogo and then bind it to the Image on the UI. StoreLogo looks very weird on screen because it is larger in size.
  2. Some other files return a relatively larger thumbnail size so it looks weird on the UI.
  3. Both storeLogo and larger thumbnail cover more space and hence hide the title of the video file from the UI (because Image height and width are auto, as they must be responsive with AdaptiveGridView).

Expectation

I want to make a solution in which I can retrieve the same size of thumbnails in all 3 cases, i.e; normal thumbnail, larger thumbnail and storelogo alternative. And I want all of them to be Uniform to Fill and scaled according to the device screen PPI.

Tried

I tried to set decoderpixelheight and width on BitmapImage object but that fixes the size of the image and it looks constricted which isn't a pretty look for the user. I know it can be achieved by setting fixed height and width on image on the UI, but then it won't be responsive according to adaptive gridview.

CODE

XAML

<controls:AdaptiveGridView Name="AllVideosGridView" 
                           Style="{StaticResource MainGridView}"
                           ItemsSource="{x:Bind ViewModel.Videos}">
    <controls:AdaptiveGridView.ItemTemplate>
        <DataTemplate x:DataType="data:Video">
            <StackPanel Style="{StaticResource MainGridViewStack}" >
                <Grid>
                    <Image  Source="{x:Bind Display, Mode=OneWay}" x:Phase="3" Style="{StaticResource GridViewImage}" x:Name="ThumbImage"/>
                    <Border ... >
                        <TextBlock ..."/>
                    </Border>
                </Grid>
                <TextBlock .../>
                <StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch" >
                    <TextBlock ...>
                    <TextBlock ..."/>
                </StackPanel>
            </StackPanel>
        </DataTemplate>
    </controls:AdaptiveGridView.ItemTemplate>
</controls:AdaptiveGridView>

<...Styles...>

<Style TargetType="Image" x:Key="GridViewImage">
    <Setter Property="Stretch" Value="UniformToFill"/>
    <Setter Property="HorizontalAlignment" Value="Center"/>
    <Setter Property="VerticalAlignment" Value="Center"/>
</Style>

<Style TargetType="controls:AdaptiveGridView" x:Key="MainGridView">
    <Setter Property="OneRowModeEnabled" Value="False"/>
    <Setter Property="DesiredWidth" Value="220"/>
    <Setter Property="SelectionMode" Value="Single"/>
    <Setter Property="StretchContentForSingleRow" Value="False"/>
    <Setter Property="IsItemClickEnabled" Value="True"/>
</Style>

Function For getting BitmapImage

 public static async Task<BitmapImage> GetDisplay(StorageFile MyVideoFile)
    {
        var bitm = new BitmapImage();
        using (var imgSource = await MyVideoFile.GetScaledImageAsThumbnailAsync(ThumbnailMode.VideosView, 200, ThumbnailOptions.UseCurrentScale))
        {
            if (imgSource != null) { await bitm.SetSourceAsync(imgSource); }
            else
            {
                var storageLogoFile = await (await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync("Assets"))
                                             .GetFileAsync("StoreLogo.png");
                bitm.UriSource = new Uri(storageLogoFile.Path);
            }
        }
        return bitm;
    }

Code To assign value to Image element

Display = await FileHelper.GetDisplay(file) // Display is property of type ImageSource and is bind to Image element in the datatemplate.

Update

Here are 2 screenshots showing the problem,

  • screenshot 1 : Showing a thumbnail marked with red arrow on bottom left corner it has more height than other normal thumbnails, hence it overlaps other elements, i.e : video file name and other stuff below it.

enter image description here

  • screenshot 2 : Showing the same kind of problem, 2 thumbnails returned null so replaced with StoreLogo.png from the assets and they are also showing same type of ugly UI.

enter image description here

I want to fix these 2 scenarios and want the size of the image to be exactly like all other normal thumbnails (as shown in the screenshots).


Solution

  • I think your issue can be fixed by replacing the top level StackPanel inside the ItemTemplate with a Grid.

    The reason being the StackPanel will give whatever the child asks for, where a Grid can restrict its children to proportional sizes. In your case, no matter how big or small each tile is, you want all images to have the same proportional size. An example is -

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="3*" /> <!--This row will take 75% of the rest of the space (i.e. total height - the height of the 3rd row)-->
            <RowDefinition Height="1*" /> <!--This row will take 25% of the rest of the space (i.e. total height - the height of the 3rd row)-->
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
    
        <Image Stretch="UniformToFill" Grid.Row="0" /> <!--0 is the default so you can safely remove Grid.Row="0" here-->
        <TextBlock Grid.Row="1" />
        <TextBlock Grid.Row="2" />
    </Grid>
    

    I actually did exactly this(0:06) in one of the apps I have developed. :) Note the images are all with different sizes but they appear to be the same on the tiles.