How to divide a grid in ListView, in UWP - xaml

<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.

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.

UWP reference control outside of data template

I'm trying to create a listview that has column headers and the lists fields mimics the width of its corresponding header. No bindings fail but the textblocks width in the data template don't match up with their headers width. I'm guessing because the data template can't find the element. Any ideas to get this to work?
<Grid Grid.Column="1" Grid.Row="1" x:Name="listViewHeaders" Height="50" VerticalAlignment="Top" Margin="10,0" >
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<!--<controls:CustomGridSplitter/>-->
<TextBlock x:Name="nameHeader" Grid.Column="0" Text="Name" />
<TextBlock x:Name="typeHeader" Grid.Column="1" Text="Type" />
<TextBlock x:Name="colorHeader" Grid.Column="2" Text="Color" />
</Grid>
<ListView x:Name="ListView" Grid.Row="1" Grid.Column="1" Background="#FF494949" Margin="10,50,10,0" ItemsSource="{Binding CurrentCardList}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Width="{Binding ActualWidth, ElementName=ListView}">
<!--<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>-->
<StackPanel Orientation="Horizontal">
<TextBlock Grid.Column="0" Width="{Binding ActualWidth, ElementName=nameHeader}" Text="{Binding Name}" />
<TextBlock Grid.Column="1" Width="{Binding ActualWidth, ElementName=typeHeader}" Text="{Binding Type}" />
<TextBlock Grid.Column="2" Width="{Binding ActualWidth, ElementName=colorHeader}" Text="{Binding Color}" />
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
</ListView>
The bindings work fine. But you're assuming that TextBlock elements in the header row will fill out the entire table cell, which they won't. They only fill as much space as much text they contain. In your case that's about 30px. You can find this information by using the Live Visual Tree feature of VS 2015.
You can solve the problem by wrapping the header TextBlock elements in another element that will fill out all available space, such as Border. Here's the solution:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid x:Name="listViewHeaders" Height="50" VerticalAlignment="Top" Margin="10,0" >
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<!--<controls:CustomGridSplitter/>-->
<Border Background="Blue" HorizontalAlignment="Stretch" Grid.Column="0" x:Name="nameHeader">
<TextBlock Text="Name" />
</Border>
<Border Background="Red" x:Name="typeHeader" Grid.Column="1">
<TextBlock Text="Type" HorizontalAlignment="Stretch" />
</Border>
<Border Background="Yellow" x:Name="colorHeader" Grid.Column="2">
<TextBlock Text="Color" HorizontalAlignment="Stretch" />
</Border>
</Grid>
<ListView x:Name="ListView" Background="#FF494949" Margin="10,50,10,0" ItemsSource="{Binding CurrentCardList}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Width="{Binding ActualWidth, ElementName=ListView}">
<!--<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>-->
<StackPanel Orientation="Horizontal">
<TextBlock Grid.Column="0" Width="{Binding ActualWidth, ElementName=nameHeader}" Text="{Binding Name}" />
<TextBlock Grid.Column="1" Width="{Binding ActualWidth, ElementName=typeHeader}" Text="{Binding Type}" />
<TextBlock Grid.Column="2" Width="{Binding ActualWidth, ElementName=colorHeader}" Text="{Binding Color}" />
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
</ListView>
</Grid>
This will create the following effect, which I believe is what you're after.
Here's the link to the complete solution - http://1drv.ms/1eUzLHl

Universal App ListView Item HorizontalAlignment

I would like to create a ListView that has right aligned items as well as left aligned. So far in all my attempts with DataTemplates and ItemContainerStyles, I am not able to get this working. The left alignment works fine as that is the default, but I cannot figure out how to get some items right-aligned. For example, this would be similar to a chat/conversation type view like the Windows Phone Messaging app.
My current XAML looks like this:
<Page
x:Class="MDControl.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MDControl"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<CollectionViewSource x:Name="Messages" Source="{Binding mMessages}"/>
<DataTemplate x:Key="SentMessageTemplate">
<StackPanel Padding="10" Margin="5" Background="Teal" HorizontalAlignment="Right" Width="Auto">
<TextBlock Text="{Binding MessageType}" FontWeight="Bold" TextWrapping="NoWrap" Foreground="White"/>
<TextBlock Text="{Binding MessageBody}" TextWrapping="Wrap" Foreground="White" />
<TextBlock Text="{Binding Timestamp}" TextWrapping="NoWrap" Foreground="White" FontStyle="Italic" FontSize="12"/>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="ReceivedMessageTemplate">
<StackPanel Padding="10" Margin="5" Background="LightGray">
<TextBlock Text="{Binding MessageType}" FontWeight="Bold" TextWrapping="NoWrap"/>
<TextBlock Text="{Binding MessageBody}" TextWrapping="Wrap"/>
<TextBlock Text="{Binding Timestamp}" TextWrapping="NoWrap" TextAlignment="Right" FontStyle="Italic" FontSize="12"/>
</StackPanel>
</DataTemplate>
<Style TargetType="ListViewItem" x:Key="SentMessageStyle">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
<Style TargetType="ListViewItem" x:Key="ReceivedMessageStyle">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
<local:MessageListTemplateSelector x:Key="MessageListTemplateSelector"
SentMessageTemplate="{StaticResource SentMessageTemplate}"
ReceivedMessageTemplate="{StaticResource ReceivedMessageTemplate}">
</local:MessageListTemplateSelector>
<local:MessageListContainerStyleSelector x:Key="MessageListContainerStyleSelector"
SentMessageStyle="{StaticResource SentMessageStyle}"
ReceivedMessageStyle="{StaticResource ReceivedMessageStyle}">
</local:MessageListContainerStyleSelector>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListView x:Name="messageList" ScrollViewer.VerticalScrollBarVisibility="Visible" ItemContainerStyleSelector="{StaticResource MessageListContainerStyleSelector}" ItemsSource="{Binding Source={StaticResource Messages}}" ItemTemplateSelector="{StaticResource MessageListTemplateSelector}" Margin="10,120,10,50" VerticalAlignment="Bottom" IsDoubleTapEnabled="False"/>
</Grid>
What can I change to get the "Sent" messages to be right aligned? Currently they show up with a Teal background which I want, but they are still Left aligned instead of Right. I am a little new to XAML, so forgive me if I'm way off here.
UPDATE: Solution
Grids were the key, I ended up having to use multiple grids to achieve the correct right-alignment, in conjunction with an ItemContainerStyle setting the HorizontalContentAlignment.
<Page
x:Class="MDControl.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MDControl"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<CollectionViewSource x:Name="Messages" Source="{Binding mMessages}"/>
<DataTemplate x:Key="SentMessageTemplate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Height="Auto" Grid.Row="1" Margin="5" HorizontalAlignment="Right">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Padding="10" Background="Teal">
<TextBlock Text="{Binding MessageType}" FontWeight="Bold" TextWrapping="NoWrap" Foreground="White" />
<TextBlock Text="{Binding MessageBody}" TextWrapping="Wrap" Foreground="White" />
<TextBlock Text="{Binding Timestamp}" TextWrapping="NoWrap" Foreground="White" FontStyle="Italic" FontSize="12" HorizontalAlignment="Right"/>
</StackPanel>
</Grid>
</Grid>
</DataTemplate>
<DataTemplate x:Key="ReceivedMessageTemplate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Height="Auto" Grid.Row="1" Margin="5" HorizontalAlignment="Left">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Padding="10" Background="LightGray">
<TextBlock Text="{Binding MessageType}" FontWeight="Bold" TextWrapping="NoWrap" />
<TextBlock Text="{Binding MessageBody}" TextWrapping="Wrap" />
<TextBlock Text="{Binding Timestamp}" TextWrapping="NoWrap" FontStyle="Italic" FontSize="12" HorizontalAlignment="Right"/>
</StackPanel>
</Grid>
</Grid>
</DataTemplate>
<local:MessageListTemplateSelector x:Key="MessageListTemplateSelector"
SentMessageTemplate="{StaticResource SentMessageTemplate}"
ReceivedMessageTemplate="{StaticResource ReceivedMessageTemplate}">
</local:MessageListTemplateSelector>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListView x:Name="messageList" ScrollViewer.VerticalScrollBarVisibility="Visible" ItemsSource="{Binding Source={StaticResource Messages}}" ItemTemplateSelector="{StaticResource MessageListTemplateSelector}" Margin="10,120,10,50" VerticalAlignment="Bottom" IsDoubleTapEnabled="False">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
</Grid>
The problem is in your DataTemplates , not in styles or etc.You must use Grid instead of Stackpanel in your DataTemplate to achieve that.
Stackpanels won't stretch to parent.They'll only get the width / height of all controls inside it.Try something like
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
You should use HorizontalAlignment property which defines the position of the element inside a parent element.<Grid x:Name="simpleGrid" height = 50 width = 100 HorizontalAlignment="right" />

ListView first item missing when binding width

i have this xaml code:
<ListView Name="MyList" ItemsSource="{Binding MyItems}"
ScrollViewer.HorizontalScrollMode="Disabled" >
<ListView.ItemTemplate>
<DataTemplate>
<Grid Width="{Binding ElementName=MyList, Path=ActualWidth}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Vertical" Grid.Column="0" Grid.ColumnSpan="2" >
<TextBlock Text="{Binding aaa}" />
<TextBlock Text="{Binding bbb}" />
<TextBlock Text="{Binding ccc}"
TextWrapping="WrapWholeWords" TextTrimming="WordEllipsis" Height="25" MaxHeight="25" Margin="0,0,10,0" />
</StackPanel>
<TextBlock Grid.Column="1" Style="{StaticResource ListTitle}" Text="{Binding restaDaPagare}"
HorizontalAlignment="Right" Margin="0,0,10,0" />
<Canvas Grid.Column="2" Height="50" Width="50" Background="{StaticResource GrayBrush}"></Canvas>
<Image Grid.Column="2" Source="/Images/img.png"
Height="50" Width="50" MinHeight="50" MinWidth="50"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
For some reasons, if i use this instruction (row 5):
<Grid Width="{Binding ElementName=MyList, Path=ActualWidth}">
the first item of MyList disappears.
If i use this code:
<Grid Width="400">
everything works well... except that I don't want to use a static Width.
Thanks for any help!
You can try to not set any width for your Grid (in your template) and add this to your ListView
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
This idea was "taken" from this question

GridView with 2 items in each row

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>