Dynamic Listview Layout in Windows Phone App 8.1 - windows-phone

I am new to Windows Phone App Development. I am showing list of some items in listview. It's working perfect for me but when the issue is with design. how can i set dynamic width of my listview. i.e. if i open my app in different resolution & mode, it should be in full width.
If i give fix width to my listview, it is not showing properly in all resolutions & mode. i am aware with * sizing but when i give * sizing, it is giving me error in App.g.i.cs file. On this statement
if (global::System.Diagnostics.Debugger.IsAttached) global::System.Diagnostics.Debugger.Break();
Please advise.

To make the items of a ListView take the full available width, set the item container style as follows:
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
To layout list view items like you wanted in the comment, you can use a Grid:
<ListView.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
... put your controls in the appropriate grid cells
</Grid>
</DataTemplate>
</ListView.ItemTemplate>

Related

Why do ListView.HeaderTemplate and ListView.ItemTemplate (UWP XAML) display differently even though I use the exact same XAML?

I have a ListView on my form and I'm setting up the ListView.HeaderTemplate and it looks like what I expect it to look like.
However, if I copy the exact Grid definition into my ListView.ItemTemplate it does not layout the same.
Altered Two Column Value Colors (Cyan and Green)
I have altered the color of the two Item column values so you can differentiate where each is showing up. I have two <x:String> values defined so data will show up in the preview layout of Visual Studio but when it runs the two layouts still look different even though they are defined the same.
No Grid.Row Defined On ItemTemplate TextBlocks
The one difference you'll notice in the XAML is that the ItemTemplate TextBlocks each only have its Grid.Column set (no Grid.Row set). That was a test and it looks the same either way.
Literally Copy / Pasted HeaderTemplate to ItemTemplate
I literally copied the HeaderTemplate to the ItemTemplate and made only the changes mentioned.
Why don't they layout the same?
<ListView.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Margin="7 0 0 0" Grid.Row="0" Grid.Column="0" Foreground="#ff0000" Text="Date" />
<TextBlock Margin="0 0 15 0" Grid.Row="0" Grid.Column="1" Foreground="#ff0000" Text="Entry Count" />
</Grid>
</DataTemplate>
</ListView.HeaderTemplate>
EDIT
If I change the ItemTemplate ColumnDefinitions to look like the following:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
Then it does get closer to what I expect, but I'm still not sure why I have to do this differently.
By default, ListViewItem won't stretch its content. Set HorizontalContentAlignment as Stretch in ItemContainerStyle.
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>

UWP Community Toolkit AdaptiveGridView control with one item only

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.

Horizontally Positioning Controls inside ListBox

I am making a UWP app and trying to place two TextBlock inside a ListBoxItem. HorizontalAlignment property doesn't seem to work.
I am trying to align the first TextBlock to the left and the second TextBlock to the right. Currently I am trying using Grids. Here's my XAML:
<Pivot.ItemTemplate>
<DataTemplate>
<ListBox ItemsSource="{Binding List}"
SelectionMode="Multiple"
ScrollViewer.HorizontalScrollMode="Disabled">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="9*"></ColumnDefinition>
<ColumnDefinition Width="1*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="{Binding read}"
HorizontalAlignment="Left"
VerticalAlignment="Center"/>
<TextBlock Text="{Binding num}"
Grid.Column="1"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DataTemplate>
</Pivot.ItemTemplate>
A couple of things you need to do here:
First, you need to stretch the alignment of the ListBoxItem, not the ListBox itself.
<ListBox>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Second, you should change Width="1*" to Width="Auto" otherwise the num TextBlock might get truncated. Then you can remove Width="9*" and add TextWrapping="Wrap" to the read TextBlock so if text will go to the next line if it's too long. You can safely remove HorizontalAlignment="Left" too.
Try to set the HorizontalContentAlignment property to stretch in the ListBox:
<ListBox ItemsSource="{Binding List}"
HorizontalContentAlignment="Stretch"
SelectionMode="Multiple"
ScrollViewer.HorizontalScrollMode="Disabled">
By default the HorizontalContentAlignment is set to left, and your listItem will not stretch to use all the available space, and that's why it's content will not be alligned properly to the right.

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>

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!