UWP Community Toolkit AdaptiveGridView control with one item only - xaml

I am making a media app with using UWP Community toolkit nuget package to use AdaptiveGridView Control, in order to show the video library contents.
Problem: When the items are very few or for example I have only 1 item it expands over the whole available width, which looks very bad, considering the fact its height is limited and doesn't changes and only width expands on whole screen, so the thumbnail of my item looks very bad. So when I have 4 or lesser items in a row (in this specific laptop resolution) they look bad due to width expansion, but more than 5 items in a row look good because they proportionate very good.
Attempt:
I tried to set max width property of stackpanel in data template of my item so that the item doesn't expand more than a specific width and it works good, but now the problem is the distance between the items, my content of item (stackpanel) remains limited but whole gridviewitem expands hence covering a lot of useless space, as show in the image below.
blue question marks show the useless space due to expansion of each item
red line box show the actual boundary of one item with expanded extra space.
Obviously the space decreases if I resize the window to smaller screen, but this is not optimal for all screen sizes.
Summary:
The default setting of adaptiveGridView (as in UWP community toolkit samples) works perfect if I have a lot of items, i.e: more than 5. But if item is one or 2 it expands all over the screen which looks bad because width becomes almost 700 at full expansion and height remains at 156 as I set it to be 156, if I remove the height of image one item will take whole screen, if there is 1 item only and that is not what I want because that will also look bad to the user (obviously).
here is my code.
gridview
<controls:AdaptiveGridView Name="SuggestionGridView"
Style="{StaticResource MainGridView}"
SelectionChanged="SelectionChanged"
ItemsSource="{x:Bind Suggestions, Mode=OneWay}">
<controls:AdaptiveGridView.ItemTemplate>
<DataTemplate x:DataType="data:Video">
<StackPanel Margin="4" MaxWidth="276">
<Grid>
<Image Source="{x:Bind Thumbnail}" Style="{StaticResource GridViewImage}"/>
<Border Style="{StaticResource TimeBorder}">
<TextBlock Text="{x:Bind Duration}" Foreground="White"/>
</Border>
</Grid>
<TextBlock Text="{x:Bind Name}" Style="{StaticResource GridViewVideoName}"/>
<TextBlock Text="{x:Bind ParentName}" Style="{StaticResource GridViewParentName}"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
<TextBlock Text="{x:Bind Views}" Style="{StaticResource GridViewViews}"/>
<TextBlock Text="Views" HorizontalAlignment="Right"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</controls:AdaptiveGridView.ItemTemplate>
</controls:AdaptiveGridView>
Styles
<Style TargetType="controls:AdaptiveGridView" x:Key="MainGridView">
<Setter Property="Grid.Row" Value="1"/>
<Setter Property="OneRowModeEnabled" Value="False"/>
<Setter Property="DesiredWidth" Value="264"/>
<Setter Property="SelectionMode" Value="Single"/>
</Style>
<Style TargetType="Image" x:Key="GridViewImage">
<Setter Property="Height" Value="156"/> <!--if I remove this property then one item expands to full availble height and width and looks really bad specially with the thumbnail.-->
<Setter Property="Stretch" Value="UniformToFill"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>

There's already a property that helps you in this case. Try setting StretchContentForSingleRow to False on the control.

Related

uwp adaptive gridview renders 1st element wrong

I am using AdaptiveGridView from UWP Community toolkit.
The Very first Item displays horribly wrong and all other Items are displayed just fine.
See in the picture below the 1st item has bigger Folder Image than others.
XAML
<Style TargetType="controls:AdaptiveGridView" x:Key="MainAdaptiveStyle">
<Setter Property="SelectionMode" Value="None"/>
<Setter Property="StretchContentForSingleRow" Value="False"/>
<Setter Property="DesiredWidth" Value="220"/>
<Setter Property="IsItemClickEnabled" Value="True"/>
<Setter Property="animations:ReorderGridAnimation.Duration" Value="400"/>
</Style>
<PivotItem Header="Folders">
<controls:AdaptiveGridView Name="FoldersLibraryGridView"
Style="{StaticResource MainAdaptiveStyle}"
ItemsSource="{x:Bind ViewModel.Folders}">
<controls:AdaptiveGridView.ItemTemplate>
<DataTemplate x:DataType="data:FolderItem">
<userTemplates:FolderTemplate />
</DataTemplate>
</controls:AdaptiveGridView.ItemTemplate>
</controls:AdaptiveGridView>
</PivotItem>
<....below is user control which is used the DataTemplate, known as FolderTemplate...>
<Grid >
<Grid.Resources>
<Style TargetType="Image" x:Key="ThumbImageStyle" >
<Setter Property="Stretch" Value="UniformToFill"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="8"/>
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="8*"/>
<RowDefinition Height="3*"/>
</Grid.RowDefinitions>
<Border x:Name="ThumbImage" Grid.Row="0">
<Border.Background>
<SolidColorBrush Color="{ThemeResource SystemAccentColor}" Opacity="0.5"/>
</Border.Background>
<Image Source="ms-appx:///Assets/FolderIcon.png"
Style="{StaticResource ThumbImageStyle}"
/>
</Border>
<Border Background="{ThemeResource SystemAltHighColor}" Grid.Row="1" Padding="8,0,4,0">
<TextBlock Text="{x:Bind FolderItem.MyFolder.DisplayName}"
Style="{StaticResource GridViewVideoName}"/>
</Border>
</Grid>
UPDATE
as You can see in the picture below, market with red line, right side of each item is faded where the folder name textblock ends, and this occurs only when ItemHeight is Explicitly set on the ApativeGridView
I think the fix is simple. First have a look at the description of this control on GitHub -
/// <remarks>
/// The number and the width of items are calculated based on the
/// screen resolution in order to fully leverage the available screen space. The property ItemsHeight define
/// the items fixed height and the property DesiredWidth sets the minimum width for the elements to add a
/// new column.</remarks>
I believe ItemsHeight is a typo there. It really should be ItemHeight. You just need to specify it (e.g. <controls:AdaptiveGridView ItemHeight="280" ... /> and the problem should go away.
Update
Your second issue is related to the DropShadowPanel in the toolkit. If you resize the window a bit you will notice that the shadows then render properly.
I had a look at the default style of the control and the HorizontalContentAlignment property is set to Left initially. So it looks like the control doesn't properly resize its inner shadow component when the size is changed.
But since you have already got a local style, you can just set it to Stretch and the issue should go away.
<Style TargetType="controls:DropShadowPanel"
x:Key="MainDropShadow">
<Setter Property="HorizontalContentAlignment"
Value="Stretch" />
Update 2
OK, so here is the reason why initially the shadow is not stretching -
The shadow size is calculated based on the Content of the DropShadowPanel control, but the shadow only monitors the SizeChanged event of the control to update its size.
What's happening in your case is that your Grid (direct child of the DropShadowPanel control) was initially arranged with a smaller size, then the shadow size was set, and then when the size of your Grid updates, because the size of DropShadowPanel is still with the same size, no SizeChanged will be invoked, hence the shadow size is not re-calculated. If you have the toolkit source code, you should be able to simply switch to monitor the SizeChanged of the Content instead and the problem should go away.
When you are setting HorizontalContentAlignment to Stretch, you are effectively saying "the child should have the same size of the parent". So when the shadow is initially sized, your Grid is already at the same size of its parent. But I feel like they must have been using Left for a reason and this should just be a temporary fix for your case.

How to make the scrollbar of a scrollviewer in XAML be non-interactive

I'm trying to create a UWP calculator app and for the display I have a slight issue. The calculator is the type that you input the text and eventually click enter and it respects orders of operation. As such, the input may get quite long so I'll need a scrollviewer around a textbox. I'm working on Windows 10 Creator's Update but the app should be backwards compatible to release version if possible.
I intend on using buttons to control cursor position, but I'd still like to have a scrollbar to indicate where you are, horizontally, in the long string. I can't figure out how to make the scrollbar there only as a visual indicator, not as a way of controlling the scrollviewer. When the mouse cursor goes near it the scrollbar expands and allows user input; this I want to avoid.
This is my display currently, very basic. How would I go about modifying that scrollviewer to my purposes?
<Border>
<ScrollViewer HorizontalScrollMode="Auto" VerticalScrollMode="Disabled" HorizontalScrollBarVisibility="Auto">
<TextBox IsReadOnly="True" Margin="5" FontSize="24" Text="long string of testing text"/>
</ScrollViewer>
</Border>
Disable hit testing on the ScrollBar:
<Border>
<ScrollViewer HorizontalScrollMode="Auto"
VerticalScrollMode="Disabled"
HorizontalScrollBarVisibility="Auto">
<ScrollViewer.Resources>
<Style TargetType="ScrollBar">
<Setter Property="IsHitTestVisible"
Value="False"/>
</Style>
</ScrollViewer.Resources>
<TextBox IsReadOnly="True"
Margin="5"
FontSize="24"
Text="long string of testing text" />
</ScrollViewer>
</Border>

How to take whole width of the screen when binding dynamic values in Universal windows Application

I try to populate radio buttons dynamically in Universal windows application. I already wrote VisualState for different
of screens. Now I try to populate the radio button, which are they have to take the whole width of the window. I able to set fixed width for every VisualState But I think that may not good practice and difficult to handle further.
<GridView Grid.Row="1" Height="auto" Width="auto" HorizontalAlignment="Stretch" ItemsSource="{Binding DamageLocationList}">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid Orientation="Horizontal" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.ItemTemplate>
<DataTemplate x:DataType="model:DamageLocations">
<Grid>
<RadioButton Style="{StaticResource ButtonRadioButtonStyle}" HorizontalContentAlignment="Center" HorizontalAlignment="Stretch" IsChecked="{Binding IsChecked, UpdateSourceTrigger=PropertyChanged}" Content="{Binding DamageLocation}" Margin="0" Click="RadioButton_Checked" />
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
As #Ashok Rathod said, you can try using UniformGrid as the ItemsPanel of your Grid to make your radio buttons take the whole width of your app's window.
Although UniformGrid is not exist in UWP. But we can implement it by ourselves or use a third party UniformGrid like what in WinRTXamlToolkit.
Using WinRTXamlToolkit for example, we can using
<toolkit:UniformGrid Rows="1" />
instead of
<VariableSizedWrapGrid Orientation="Horizontal" />
Here toolkit is the namespace of WinRTXamlToolkit.Controls:
xmlns:toolkit="using:WinRTXamlToolkit.Controls"
As I didn't set Columns property, it will be the default value which is 0. A value of zero (0) for the Columns property specifies that the column count is computed based on the number of rows and the number of visible child elements that are in the Grid. Since I set Rows to 1, all the items will be put in one row and have the same width.
After this, you may also need to set ItemContainerStyle to make the radio buttons stretch like:
<GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</GridView.ItemContainerStyle>

How to change Background Color of ListBoxItem based on ListBoxItem Value

I'm currently creating a Windows 8.1 Store app that acts as a task tracker. My current problem is that I want to change the Items listed in listview to represent their priority. I want to do this by Changing the Background color. IE: Red = High, Blue = Medium, and Green = Low.
The ListBoxItems themselves follow a Template, below is the relevant Text field I want to base changes from x:Name=priorityBind.
<StackPanel Orientation="Horizontal">
<TextBlock Text="Priority: " Margin="10, 0, 10, 10" />
<TextBlock x:Name="priorityBind" Text="{Binding Path=Priority}" Margin="10, 0, 10, 10"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Notes: " Margin="10, 0, 10, 10" />
<TextBlock Text="{Binding Path=Notes}" Margin="10, 0, 10, 10"/>
</StackPanel>
</StackPanel>
</Grid>
</DataTemplate>
All the examples I can find seem to be done with outdated version of the Store Apps. Setting up triggers seems to be the suggest route to go, but it no longer seems to work in the updated version. Below is a snippet of my ListView Code. How do I modify it so that it only updates the background color to green if the priority textbox holds a value of "Low"?
<ListView x:Name="eventsListView" Grid.Row="1" Grid.Column="1"
ItemTemplate="{StaticResource eventTemplate}">
<ListView.Resources>
<Style TargetType="ListViewItem">
<Style.Setters>
<Setter Property="BorderBrush"
Value="White" />
<Setter Property="BorderThickness"
Value="5"/>
<Setter Property="Background"
Value="Green"/>
</Style.Setters>
</Style>
</ListView.Resources>
</ListView>
You can specify which priority should use which tempalte by using ItemTemplateSelector
ItemTemplateSelector lets ListView to render different templates based on the property you give as parameter.This is the best practice solution AFAIK.

WP 8.1 bottom to top infinite scrolling

I have explored ISupportIncrementalLoading and seen MS sample and other examples for infinite scrolling behaviour.
But I want bottom to top scrolling where items are added on top on scrolling bottom to top.
Edit:I have found a workaround for this. I have rotated listview by 180 degree and datatemplate by 180 degree which helped me achieve desired functionality.
<ListView x:Name="GridViewMain" IncrementalLoadingThreshold="2" RenderTransformOrigin="0.5,0.5">
<ListView.RenderTransform>
<RotateTransform Angle="180"></RotateTransform>
</ListView.RenderTransform>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.Resources>
<DataTemplate x:Key="DataTemplateGridViewMain">
<Grid HorizontalAlignment="Stretch" Background="#FF7C1A9B" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<RotateTransform Angle="180"/>
</Grid.RenderTransform>
<TextBlock HorizontalAlignment="Left" Text="{Binding}" VerticalAlignment="Center" FontSize="20" FontFamily="Tempus Sans ITC" />
</Grid>
</DataTemplate>
</ListView.Resources>
<ListView.ItemTemplate>
<StaticResource ResourceKey="DataTemplateGridViewMain" />
</ListView.ItemTemplate>
</ListView>
Is this solution has any perf impact or is there any alternate way to do this?
not sure if this will fit your needs, but I had to do something similar when creating a chat conversation screen, and was able to achieve this using ExtendedListView: https://www.nuget.org/packages/ExtendedListView
We load the most recent items, and use ScrollIntoView(lastMessage) to position the cursor at the bottom. Normally you would use MoreDataRequested event to get items when it scrolls to the bottom, but instead we reversed it and used the PullToRefreshRequested to simulate scrolling to the top, changing the loading template to say "loading more messages".
works pretty well for us, I hope this is helpful!