GridView with 2 items in each row - xaml

I want to show two GridViewItems in each row, with equal width. how can I achieve that?
I am using following template but it is not taking equal space between items.
<DataTemplate x:Key="GridViewItemTestTemplate">
<StackPanel Orientation="Horizontal">
<Border Background="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}" Margin="0,9.5,0,0">
<Image Height="79" Width="79"/>
</Border>
<StackPanel Grid.Column="1" Margin="14.5,0,0,0">
<TextBlock Text="{Binding Title}" Style="{ThemeResource ListViewItemTextBlockStyle}"/>
<TextBlock Text="Subtitle" Style="{ThemeResource ListViewItemSubheaderTextBlockStyle}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
here is my gridview.
<GridView ItemsSource="{Binding MyData}" ItemTemplate="{StaticResource GridViewItemTestTemplate}"
IsSwipeEnabled="False" SelectionMode="Single" HorizontalContentAlignment="Stretch">
</GridView>

Replace your StackPanel with this
<Grid Grid.Column="1" Margin="14.5,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Title}" Style="{ThemeResource ListViewItemTextBlockStyle}"/>
<TextBlock Grid.Column="1" Text="Subtitle" Style="{ThemeResource ListViewItemSubheaderTextBlockStyle}"/>
</Grid>
Grids resize themselves dynamically versus StackPanels. The ColumnDefinition Width="*" is the important part, telling the panel to set the width of each column to fill the width of the grid, and for each column to have the same width.
edit: Is this the hehavior you want? Not as pretty as dynamic resizing but the same width requirement with 2 items per row basically force all items to have the same width
<GridView Width="200">
<GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="Width" Value="80" />
</Style>
</GridView.ItemContainerStyle>
...
</GridView>

Related

UWP - Can I bind a textblock in a datatemplate to a grid column's width outside of it?

Relatively new to UWP, is it possible to bind a TextBlock of a DataTemplate (used for ItemTemplate in a listview) to a column outside of it, or is there any way to set the DataTemplate's grid columns' widths to the size of the "MainGrid"'s column definition widths? Code below to show what I'm trying to achieve.
<Grid x:Name="MainGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Column1" Width="*"/>
<ColumnDefinition x:Name="Column2" Width="8*"/>
<ColumnDefinition x:Name="Column3" Width="*"/>
</Grid.ColumnDefinitions>
<ListView Name="recordList" ItemsSource="{x:Bind _recordingList, TargetNullValue=0}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:Recording">
<Grid>
<TextBlock Grid.Column="{Binding Column1}" Name="TextBlock_Time" Text="{x:Bind Time}"/>
<TextBlock Grid.Column="{Binding Column2}" Name="TextBlock_Message" Text="{x:Bind Message}"/>
<TextBlock Grid.Column="{Binding Column3}" Name="TextBlock_Type" Text="{x:Bind Type}"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
With the image below, I suppose imagine the red lines are the window. Essentially trying to get the columns to adapt to the window size changing.
example
I think you want listviewitem to be streched to the size of window. To achieve that you need to set HorizontalContentAlignment of listviewitem has to set to stretch in ItemContainerStyle
<ListView x:Name="MessagesList" BorderThickness="1" ItemsSource="{x:Bind _recordingList, TargetNullValue=0}" BorderBrush="Black">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
<Setter Property="Padding" Value="0"></Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:Recording">
<Grid BorderThickness="0,1,0,0" Padding="20" BorderBrush="{ThemeResource SystemControlForegroundBaseMediumBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="8*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{x:Bind Time,Mode=OneWay}"></TextBlock>
<TextBlock Grid.Column="1" Text="{x:Bind Message,Mode=OneWay}"></TextBlock>
<TextBlock Grid.Column="2" Text="{x:Bind Type,Mode=OneWay}"></TextBlock>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
You just need to move your columns to the template itself.
DataTemplate is a scheme that describes what and where. Because it's in ItemTemplate , then it means it's for every item.
<ListView Name="recordList" ItemsSource="{x:Bind _recordingList, TargetNullValue=0}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:Recording">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Column1" Width="*" />
<ColumnDefinition x:Name="Column2" Width="8*" />
<ColumnDefinition x:Name="Column3" Width="*" />
</Grid.ColumnDefinitions>
<TextBlock
Name="TextBlock_Time"
Grid.Column="0"
Margin="20"
Foreground="Red"
Text="{x:Bind Time}" />
<TextBlock
Name="TextBlock_Message"
Grid.Column="1"
Margin="20"
Foreground="Green"
Text="{x:Bind Message}" />
<TextBlock
Name="TextBlock_Type"
Grid.Column="2"
Margin="20"
Foreground="LightBlue"
Text="{x:Bind Type}" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
That should make your items look like this.
Check out documentation, as it's explaining it nicely. There are templates in templates. So you can template a Container (how it should display items), and Items (how every item should look like).
Templates
Remember about HorizontalAlignment="Stretch" etc. as this means that the textblock (or Grid) will occupy all of it's space available (horizontally). Tinker with it and you'll get a grasp on how it works.

How to divide a grid in ListView, in UWP

<Grid Grid.Row="3" HorizontalAlignment="Stretch">
<ListView x:Name="lvAlert" HorizontalAlignment="Stretch">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70*"/>
<ColumnDefinition Width="30*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Background="{Binding ColorValue }" >
<TextBlock Text="{Binding AlertType}" Foreground="White" Height="35" HorizontalAlignment="Stretch"/>
</Grid>
<Grid Grid.Column="1" Background="{Binding ColorValue }" >
<TextBlock Text="{Binding AlertTypeValue}" Foreground="Black" Height="35" HorizontalAlignment="Stretch"/>
</Grid>
<TextBlock Grid.Column="0" Text="{Binding AlertType}" Foreground="{Binding ColorValue }" Width="400" Height="40"/>
<TextBlock Grid.Column="1" Text="{Binding AlertTypeValue}" Foreground="{Binding ColorValue }" Width="400" Height="40"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
When I run the above code I got an output as in a single line without getting properly separation in 70% and 30%. Can anyone solve this?
By default, ListView's items don't stretch horizontally, but stick to the left.
Your problem should be solved by this code:
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment"
Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
When I run the above code I got an output as in a single line without getting properly separation in 70% and 30%. Can anyone solve this?
It's because the Height of ColumnDefinitions should be set 7* and 3* instead of 70* and 30*:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="7*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
For details of Grid usage, you can refer to Gird Class.

Horizontally grouped ListView in Windows Store apps

I want the groups in my grouped ListView to show horizontally instead of vertically. I tried this solution, but the groups are still under each other instead of next to each other. Arranging ListView items Horizontally
Here's my XAML (this is the original, unmodified):
<ListView Name="slotlist"
ItemsSource="{Binding Source={StaticResource cvsDelivery}}"
Margin="0,0,10,0"
IsItemClickEnabled="True"
ItemClick="onSlotBooked">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid Width="{Binding ActualWidth, ElementName=grRoot}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding timeRange}" Grid.Column="0" FontWeight="Bold"
Margin="10,0,0,0"
Foreground="{Binding Fontcolor}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Style="{StaticResource BaseTextBlockStyle}"/>
<TextBlock Text="{Binding slotPrice}" Grid.Column="1" FontWeight="Bold"
Margin="0,0,20,0"
Foreground="{Binding Fontcolor}"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Style="{StaticResource BaseTextBlockStyle}"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.GroupStyle>
<GroupStyle HidesIfEmpty="True">
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock
Text="{Binding date}"
Foreground="#FF005299"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
To get the ListView to be shown horizontally you can modify the ItemsPanel, like so:
<ListView>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>

ListView is not Scrollable

I have the following ListView in my xaml layout:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<TextBlock Text="{StaticResource AppName}" Style="{StaticResource TitleTextBlockStyle}"/>
</StackPanel>
<StackPanel Grid.Row="1">
<ListView x:Name="lstStatus">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="12">
<Image Source="ms-appx:///Assets/Logo.png" Margin="12" Width="150" Height="150"></Image>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Path='Fullname'}" Style="{StaticResource ListViewItemSubheaderTextBlockStyle}"></TextBlock>
<TextBlock Text="{Binding Path='FormattedCreationTime'}" TextWrapping="WrapWholeWords"></TextBlock>
<TextBlock Text="{Binding Path='Text'}" Style="{StaticResource ListViewItemContentTextBlockStyle}" TextWrapping="WrapWholeWords" Margin="12"></TextBlock>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</Grid>
However, I met two problems:
The list is not scrollable when it is longer than the screen.
The TextBlocks does not wrap at all although I already set TextWrapping.
I am pretty new to Windows Phone design. Please tell me where did I do wrong.
The StackPanel takes as much space as it needs. As the ListView grows, the StackPanel expands to allow it to grow, hence you cannot scroll to see the items you don't see on the screen.
Put the ListView in a Grid or limit the Height of the StackPanel.
<Grid Grid.Row="1">
<ListView x:Name="lstStatus">
...
Similar problem occurs in your ItemTemplate, and the fix is also similar.
<DataTemplate>
<Grid Margin="12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image ...
<StackPanel Grid.Column="1">
<TextBlock ....
</StackPanel>
</Grid>
</DataTemplate>

XAML Columndefinitions width * not taking available space

I know how the columndefinition works in XAML but there is something I want to do and don't know how.
I want 4 columns like that:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="110" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="80" />
<ColumnDefinition Width="80" />
</Grid.ColumnDefinitions>
column has fixed width
column must take all the available space (yes it is between columns and this is exactly the problem)
column has fixed width
column has fixed width
The 2nd column contains text and the problem is that when that text is too short the 2nd column does not take all the available space. it get's smaller automatically and this for each row. I can make it work with this code in the textblock:
MinWidth="2000"
But it's not the good way since this number could be too low when the screen is big.
Here the whole listview containing the 4 columns:
<ListView Grid.Row="1" Grid.ColumnSpan="4" ItemsSource="{Binding blabla}" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="110" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="80" />
<ColumnDefinition Width="80" />
</Grid.ColumnDefinitions>
<Image Height="110" Width="110" Grid.Column="0" Source="{Binding blabla}" HorizontalAlignment="Stretch" />
<TextBlock Text="{Binding blabla}" TextWrapping="Wrap" Margin="5,0,0,0" Grid.Column="1" FontSize="16" HorizontalAlignment="Stretch" TextAlignment="Left" FlowDirection="LeftToRight" MinWidth="2000" VerticalAlignment="Center" ScrollViewer.HorizontalScrollBarVisibility="Disabled" FontStretch="UltraCondensed"/>
<TextBlock Grid.Column="2" TextWrapping="Wrap" Foreground="Black" Margin="5,0,0,0" HorizontalAlignment="Stretch" VerticalAlignment="Center"/>
<Image Source="{Binding blabla, Converter={StaticResource ImgConverter}}" Grid.Column="3" Width="76" Height="76" HorizontalAlignment="Center" Stretch="None" VerticalAlignment="Center" Margin="0"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Your layout is well-defined but missed a small thing that is causing that the content of the Listviewitem is margined to the left because that is defined in the default ListViewItemStyle which is named "ItemContainerStyle" for the ListView Control .
All what you need to do is add this ListViewItemStyle that I've modified to stretch the content Horizontally and Vertically across all the available space for the item to your Resources
<Style x:Key="StretchedListViewItemStyle"
TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment"
Value="Stretch" />
<Setter Property="VerticalContentAlignment"
Value="Stretch" />
</Style>
Then set it as the ItemContainerStyle for the ListView as follows:
<ListView Grid.Row="1" Grid.ColumnSpan="4" ItemsSource="{Binding blabla}" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" ItemContainerStyle="{StaticResource StretchedListViewItemStyle}"/>