Horizontally grouped ListView in Windows Store apps - xaml

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>

Related

Can't get VariableSizedWrapGrid to wrap

I'm having issues getting the VariableSizedWrapGrid to wrap horizontally. All I can seem to get are my elements stacked vertically in a single column. I'm not sure what I'm missing.
Ideally I would like to have 3 columns of input fields. The number of fields changes depending on the table selected so they need to just, you know, wrap.
<ScrollViewer
Grid.Column="0"
Grid.ColumnSpan="2"
Grid.Row="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<VariableSizedWrapGrid
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Orientation="Horizontal">
<ItemsControl
ItemsSource="{x:Bind ViewModel.CurrentRow.Values}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="models:RowValue">
<Grid Width="Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock
Text="{x:Bind key.ColumnValidation.column_label}"
Margin="0"
Padding="0"
Grid.Column="0">
</TextBlock>
<TextBox
Grid.Column="1"
Visibility="{x:Bind vm:Converters.IsTextBoxField(key.ColumnValidation.data_type)}"
Text="{x:Bind value}">
</TextBox>
<RichTextBlock
Visibility="{x:Bind vm:Converters.IsHyperlinkField(key.ColumnValidation.data_type)}">
<Paragraph>
<Span>
<Hyperlink />
</Span>
</Paragraph>
</RichTextBlock>
<DatePicker
Visibility="{x:Bind vm:Converters.IsDateField(key.ColumnValidation.data_type)}">
</DatePicker>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</VariableSizedWrapGrid>
</ScrollViewer>
Turns out I didn't fully understand how ItemsControl works. Managed to get it working like so:
<ScrollViewer
Grid.Column="0"
Grid.ColumnSpan="2"
Grid.Row="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<ItemsControl
Height="Auto"
Width="Auto"
ItemsSource="{x:Bind EditRow.Values}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid
Orientation="Horizontal"
MaximumRowsOrColumns="4"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
ItemWidth="200"
ItemHeight="75">
</VariableSizedWrapGrid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="models:RowValue">
<Grid
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
Width="190"
Margin="5">
<TextBox
Header="{x:Bind key.ColumnValidation.column_label}"
Visibility="{x:Bind vm:Converters.IsTextBoxField(key.ColumnValidation.data_type)}"
Text="{x:Bind value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
</TextBox>
<TextBox
Header="{x:Bind key.ColumnValidation.column_label}"
Visibility="{x:Bind vm:Converters.IsHyperlinkField(key.ColumnValidation.data_type)}"
Text="{x:Bind value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
</TextBox>
<!-- todo: create converter for fusion date format -->
<Viewbox VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<DatePicker
Header="{x:Bind key.ColumnValidation.column_label}"
Visibility="{x:Bind vm:Converters.IsDateField(key.ColumnValidation.data_type)}">
</DatePicker>
</Viewbox>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>

GridView ItemTemplate Full Width

My question is: how can I stretch the DataTemplate to the full width of the screen. I've tried many solutions but they does not work.
I've tried HorizontalContentAlignment, setting GridView.ItemContainerStyle and etc. But nothing works. Can anybody explain me how can I do this?
Here is part of my code:
<Grid Style="{StaticResource GeneralAppBackground}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Pivot x:Name="AccountInfoOptions" Grid.Row="1">
<PivotItem Header="История">
<GridView ItemsSource="{x:Bind CheckoutList}" Margin="5,0,5,0">
<GridView.ItemTemplate>
<DataTemplate x:DataType="data:UserCheckout">
<StackPanel Orientation="Horizontal" BorderBrush="Transparent" Background="White" Padding="5" Margin="0,5,0,0">
<StackPanel Grid.Column="0" Orientation="Vertical" VerticalAlignment="Center" Margin="0,0,10,0">
<TextBlock FontSize="14" Text="{x:Bind CheckoutDate}" Foreground="#979797" />
<TextBlock FontSize="14" Text="{x:Bind CheckoutTime}" Foreground="#979797" />
</StackPanel>
<StackPanel Grid.Column="1" VerticalAlignment="Center">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{x:Bind CheckoutSum}" FontSize="22" FontWeight="Bold" />
<Image Source="/Assets/TengeIcon.png" Width="20" Margin="5,0,0,0"/>
</StackPanel>
<TextBlock Text="{x:Bind CheckoutTitle}" TextAlignment="Center" />
</StackPanel>
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</GridView.ItemContainerStyle>
</GridView>
</PivotItem>
</Pivot>
The key to making it work, is changing the ItemsPanelTemplate. Define it as a page resource:
<Page.Resources>
<ItemsPanelTemplate x:Key="ItemsPanelTemplate">
<ItemsStackPanel />
</ItemsPanelTemplate>
</Page.Resources>
Now set it as the ItemsPanel for your GridView:
<GridView ItemsSource="{x:Bind CheckoutList}"
Margin="5,0,5,0"
ItemsPanel="{StaticResource ResourceKey=ItemsPanelTemplate}">
This will allow individual items to stretch across the full width. You will still need to replace the root StackPanel in your DataTemplate with a Grid as Nikita suggested:
<DataTemplate x:DataType="local:UserCheckout">
<Grid BorderBrush="Transparent" Background="White" Padding="5" Margin="0,5,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Orientation="Vertical" VerticalAlignment="Center" Margin="0,0,10,0">
<TextBlock FontSize="14" Text="{x:Bind CheckoutDate}" Foreground="#979797" />
<TextBlock FontSize="14" Text="{x:Bind CheckoutTime}" Foreground="#979797" />
</StackPanel>
<StackPanel Grid.Column="1" VerticalAlignment="Center">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{x:Bind CheckoutSum}" FontSize="22" FontWeight="Bold" />
<Image Source="/Assets/TengeIcon.png" Width="20" Margin="5,0,0,0"/>
</StackPanel>
<TextBlock Text="{x:Bind CheckoutTitle}" TextAlignment="Center" />
</StackPanel>
</Grid>
</DataTemplate>
You already have the Grid.Column property set correctly for the inner StackPanels. It seems you were attempting to use a Grid there before.

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>