Spacing between ListItems on Horizontal Stackpanel - c#

How do I control the amount of space between items coming from the Biding 'Shorthand'? At the moment I have gaps between which seem to be dependent on the size of the value of 'Shorthand' itself (so if the value is 1 character the gap between it and the next value is bigger compared to if the value is 2 characters long).
I have tried putting the margin and padding to zero in various places to no avail.
<ListView ItemsSource="{Binding Rounds}" IsItemClickEnabled="False" ItemClick="ItemView_ItemClick" ContinuumNavigationTransitionInfo.ExitElementContainer="True">
<ListView.ItemTemplate>
<DataTemplate >
<StackPanel>
<TextBlock Style="{ThemeResource ListViewItemSubheaderTextBlockStyle}">
<Run Text="Round "/>
<Run Text="{Binding RoundNumber}" />
</TextBlock>
<ListView ItemsSource="{Binding Formations}" >
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Shorthand}" Style="{ThemeResource ListViewItemTextBlockStyle}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

I'm not sure where in the Template the margin/padding is set. As a workaround you may try to set a negative Margin to your ItemContainerStyle:
<ListView Name="myList">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Margin" Value="0,0,0,-20" />
</Style>
</ListView.ItemContainerStyle>
// rest of the code

The first occurrence of ItemView of ListView is defined inline. So when ItemSource is set, the ItemTemplate is applied to EVERY item.
ListView.ItemTemplate encompassing Binding Shorthand. Place it in a Grid and define Grid.ColumnDefinitions to Width="Auto" or "*" for DataTemplate.
The StackPanel may help position it better. You will have to adjust Grid defs to your display requirements needed.
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" VerticalAlignment="Top" Margin="10,0,0,0">
<TextBlock Text="{Binding Shorthand}" Style="{ThemeResource ListViewItemTextBlockStyle}" />
</StackPanel>
</Grid>
</DataTemplate>

Related

UWP Stretch GridView

How to stretch GridViewItem horizontaly? Trying to set property HorizontalContentAlignment or style property in ItemContainerStyle. This does not help.
Here is a code:
<GridView ItemsSource="{x:Bind Banks}" SelectionMode="None" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</GridView.ItemContainerStyle>
<GridView.ItemTemplate>
<DataTemplate x:DataType="model:Bank">
<Grid HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding Name}" Grid.Column="0" />
<GridView ItemsSource="{x:Bind Departments}" Grid.Row="1" HorizontalContentAlignment="Stretch" IsItemClickEnabled="True" VerticalContentAlignment="Stretch">
<GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</GridView.ItemContainerStyle>
<GridView.ItemTemplate>
<DataTemplate x:DataType="model:Department">
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="40" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding Name}" Grid.Column="0" />
<TextBlock Text="{Binding Address}" Grid.Column="0" Grid.Row="1" />
<TextBlock Text="{Binding USD.Date}" Grid.Column="1" Grid.RowSpan="2"/>
<TextBlock Text="{Binding USD.Sell}" Grid.Column="2" />
<TextBlock Text="{Binding USD.Buy}" Grid.Column="2" Grid.Row="1"/>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
By default,GridView uses ItemsWrapGrid as the panel to position and arrange GridViewItem, you can find this from Live Visual Tree:
Although you've set HorizontalContentAlignment or HorizontalAlignment to Stretch for GridViewItem, but the size of GridViewItem is limited by ItemsWrapGrid.
ItemsWrapGrid positions child elements sequentially from left to right or top to bottom in an ItemsControl that shows multiple items. When elements extend beyond the container edge, elements are positioned in the next row or column.
So in ItemsWrapGrid, items won't be stretched.
If you want to stretch GridViewItem horizontaly, we can use ItemsStackPanel instead of ItemsWrapGrid like following:
In Resources, add a ItemsPanelTemplate with ItemsStackPanel:
<Page.Resources>
<ItemsPanelTemplate x:Key="MyItemsPanelTemplate">
<ItemsStackPanel />
</ItemsPanelTemplate>
</Page.Resources>
Then use this template in GridView:
<GridView HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
ItemsPanel="{StaticResource MyItemsPanelTemplate}"
ItemsSource="{x:Bind Banks}"
SelectionMode="None">
...
<GridView Grid.Row="1"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
IsItemClickEnabled="True"
ItemsPanel="{StaticResource MyItemsPanelTemplate}"
ItemsSource="{x:Bind Departments}">
...
</GridView>
...
</GridView>
Or we can use ListView instead of GridView as ListView's default ItemsPanel is ItemsStackPanel.

Applying The Same Height For All DataGridColumns when MaxWidth of the Header Is Set

I have an ItemsControl containing dynamically changable number of DataGrids:
<ItemsControl ItemsSource="{Binding Table.Columns}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" VerticalAlignment="Stretch"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplateSelector>
<local:ColumnTemplateSelector InputParameterColumnTemplate="{StaticResource InputParamterColumn}"
SingleParameterColumnTemplate="{StaticResource SingleParameterColumn}"/>
</ItemsControl.ItemTemplateSelector>
</ItemsControl>
The template for the "SingleParameterColumn" is defined like this:
<DataTemplate x:Key="SingleParameterColumn">
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Cells}"
RowHeight="25" RowHeaderWidth="0" >
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}"
TextWrapping="Wrap"
TextAlignment="Center"
MaxWidth="60">
</TextBlock>
<Button>
<Image ... />
</Button>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
<DataGridTemplateColumn.CellTemplateSelector>....
</DataGridTemplateColumn.CellTemplateSelector>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
There is always one InputParameterColumn and at least one SingleParameterColumn. The InputParameterColumn has a fixed header name, whereas the header of the SingleParameterColumn can be arbitrarily long.
Since I do not want to have very wide columns I have defined the MaxWidth of the TextBlock in the header template to 60, which causes the header to be higher if the name of a column is very long.
This causes the columns to have different heights depending on the length of the header name.
Is there any way I can find out how tall is the tallest header in my ItemsControl and then set the same height for all the other headers so that my columns then all have the same size?
I could finally reproduce your problem, and managed to solve it with these changes:
Set Grid.IsSharedSizeScope="True" on the StackPanel that serves as ItemsPanel for your ItemsControl
On you ItemTemplate, Change the StackPanels of the HeaderTemplates for Grids
On each Grid, define a single row with the same SharedSizeGroup identifier
ItemsControl:
<ItemsControl ItemsSource="{Binding Table.Columns}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" VerticalAlignment="Stretch"
Grid.IsSharedSizeScope="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplateSelector>
<local:ColumnTemplateSelector InputParameterColumnTemplate="{StaticResource InputParamterColumn}"
SingleParameterColumnTemplate="{StaticResource SingleParameterColumn}"/>
</ItemsControl.ItemTemplateSelector>
</ItemsControl>
ItemTemplate:
<DataTemplate x:Key="SingleParameterColumn">
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Cells}"
RowHeight="25" RowHeaderWidth="0">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"
SharedSizeGroup="DataGridHeaderRow" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding Name}"
TextWrapping="Wrap"
TextAlignment="Center"
MaxWidth="60">
</TextBlock>
<Button Grid.Column="1">
<Image ... />
</Button>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
<DataGridTemplateColumn.CellTemplateSelector>....
</DataGridTemplateColumn.CellTemplateSelector>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
You could write a behavior that attaches to the header TextBlock, and does the following:
subscribe to the SizeChanged event
store somewhere (static prop or helper class...) the largest size
if this largest size changes, just change the height of all elements the behavior is attached to

Make grid width same as listview in DataTemplate

I'd like to have grid width same as listview width, right now it looks like:
But what i want to reach is:
Code:
<DataTemplate x:Key="Shared">
<ListView Name="_lv" ItemsSource="{Binding lista}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="{Binding name}"/>
<Grid Grid.Column="1">
<WrapPanel Orientation="Horizontal">
<telerik:RadNumericUpDown Name="minRNUD" Value="0" />
<Button Width="40" Height="40" Style="{StaticResource MButton}" Margin="0" Padding="1">
<Button.Content>
<Image Source="/myProject;component/Pictures/clr.png" Width="30" Height="30" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Button.Content>
</Button>
</WrapPanel>
</Grid>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</DataTemplate>
Any ideas?
Thanks!
HorizontalContentAlignment property determines the horizontal alignment of the content
setting HorizontalContentAlignment on the list items may affect it's content not the item itself
however setting the same on the parent items control like ListBox, ListView etc. will affect the alignment of their content or can say the items
so simply moving the HorizontalContentAlignment property to the parent ItemsControl (ListBox, ListView etc). will ensure the desired alignment of the items.
so simply add the property HorizontalContentAlignment="Stretch" to the parent items control of the desired item.

ListViewItem is not expanding to the width of the page

I am defining a ListView like this:
<DataTemplate x:Key="LibraryItemTemplate">
<Grid Height="191"
UseLayoutRounding="True">
<Grid.Background>
<ImageBrush Stretch="Fill"
ImageSource="Assets/BookShelf.jpg" />
</Grid.Background>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid x:Name="gridTitle"
Background="{Binding Text, Converter={StaticResource LibraryItemBackgroundConverter}, ElementName=tbTitle}"
Margin="6,4,6,13">
<TextBlock x:Name="tbTitle"
TextWrapping="Wrap"
VerticalAlignment="Center"
RenderTransformOrigin="0.5,0.5"
Width="100"
Margin="0,0,0,0.2"
TextAlignment="Center"
FontSize="24"
FontWeight="Bold"
UseLayoutRounding="False"
d:LayoutRounding="Auto">
<TextBlock.RenderTransform>
<CompositeTransform Rotation="-90" />
</TextBlock.RenderTransform>
<Run Text="{Binding Title}" />
</TextBlock>
</Grid>
<Grid x:Name="gridBooks"
Grid.Column="1"
Margin="0">
<GridView x:Name="booksGridView"
AutomationProperties.AutomationId="ItemGridView"
AutomationProperties.Name="Grouped Items"
ItemsSource="{Binding Items}"
ItemTemplateSelector="{StaticResource textbookTemplateSelector}"
SelectionMode="Multiple"
IsItemClickEnabled="True"
ItemClick="booksGridView_ItemClick"
SelectionChanged="booksGridView_SelectionChanged"
IsSwipeEnabled="false"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid Orientation="Horizontal" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
</Grid>
</Grid>
</DataTemplate>
<Grid Grid.Row="1"
Margin="80,0,12,0">
<ListView x:Name="libraryListView"
AutomationProperties.AutomationId="VideoListView"
AutomationProperties.Name="Videos"
TabIndex="1"
Padding="0,0,4,0"
ItemsSource="{Binding}"
IsSwipeEnabled="False"
SelectionChanged="LibraryListView_SelectionChanged"
ItemTemplate="{StaticResource LibraryItemTemplate}"
ItemContainerStyle="{StaticResource LibraryListViewItemStyle}">
</ListView>
</Grid>
The problem I am having is that each ListViewItem has different width, based on the number of elements in the GridView.
How can I force each ListViewItem to use the maximum width of the screen (so that the "Assets/BookShelf.jpg" will be the same for each of the ListViewItems).
Please see the attached image to better demonstrate my problem.
Thanks
To give you the best answer I would need a dummy screenshot of the expected layout, but it sound like you want the right column to stretch, which would be accomplished by setting its width to star (*) instead of Auto (which takes up only the space needed).
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" /> <!-- ONLY TAKE UP SPACE NEEDED -->
<ColumnDefinition Width="*" /> <!-- TAKE UP ALL AVAILABLE SPACE -->
</Grid.ColumnDefinitions>
The answer is with this code:
<ListView ..>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalAlignment" Value="Strech" />
.
.
.
.
<Setter Property="HorizontalContentAlignment" Value="Strech" />
</Style>
</ListView.ItemContainerStyle>
...
</ListView>
In this code we set the ItemContainerStyle: HorizontalAlignment = "Strech" and HorizontalContentAlignment = "Strech" and it made the trick.

How to bind data in an item control to stack panel?

I'm trying to create a custom ListBox. That receives a list with three properties:
SubjectName
Problems
AverageScore
The property Problems is another list which contains several Problem class. This is the data template I'm creating.
<DataTemplate x:Key="SubjectDataTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<StackPanel Margin="5">
<StackPanel Orientation="Horizontal" TextBlock.FontWeight="Bold" >
<TextBlock Text="{Binding Path=ProblemNumber, FallbackValue=ProblemNumber}" />
<TextBlock Text="{Binding Path=SubjectName, FallbackValue=SubjectName}" Padding="3,0,0,0"/>
</StackPanel>
<TextBlock Text="{Binding Path=AverageScore, FallbackValue=AverageScore}" />
<ItemsControl ItemsSource="{Binding Problems}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<StackPanel Background="Aqua" Orientation="Vertical" Margin="5">
<Rectangle Fill="Red" Height="20" Width="20" />
</StackPanel>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<!--<TextBlock Text="{Binding Path=Role, FallbackValue=Role}" />-->
</StackPanel>
</Grid>
</DataTemplate>
But I've got a problem trying to show Problems data. I'm trying to show each element from Problems list in a stack panel with ortientation horizontal, but I get each stack panel separated.
I need to put the red rectangles inside the stack control. For example, the ten rectangles from Times Tables should be in one only stack panel.
UPDATE 1:
Something like this:
According to the graph, the first stack panel (background aqua) must contain 10 red rectangles.
UPDATE 2:
I'm verifying showing the data from problem in a textBlock and it works:
<ItemsControl ItemsSource="{Binding Problems}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding IsCorrect}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Background="Gainsboro" Margin="5" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
You need to use nested ItemsControls - One for the Vertical list and one for the Horizontal List.
<ItemsControl ItemsSource="{Binding Problems}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding Problems}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Height="20" Width="20" Margin="1,0">
<Rectangle.Style>
<Style TargetType="{x:Type Rectangle}">
<Setter Property="Fill" Value="Red" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsCorrect}" Value="True">
<Setter Property="Fill" Value="Blue" />
</DataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Background="Aqua" Margin="5" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
In your ItemsControl.ItemsPanel make the StackPanel orientation Horizoantal
Is this what you are looking for?
UPDATED:
<DataTemplate x:Key="SubjectDataTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<StackPanel Margin="5">
<StackPanel Orientation="Horizontal" TextBlock.FontWeight="Bold" >
<TextBlock Text="{Binding Path=ProblemNumber, FallbackValue=ProblemNumber}" />
<TextBlock Text="{Binding Path=SubjectName, FallbackValue=SubjectName}" Padding="3,0,0,0"/>
</StackPanel>
<TextBlock Text="{Binding Path=AverageScore, FallbackValue=AverageScore}" />
<ItemsControl ItemsSource="{Binding Problems}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<Rectangle Fill="Red" Height="20" Width="20" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Background="Aqua" Orientation="Horizontal" Margin="5"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</StackPanel>
</Grid>
</DataTemplate>

Categories

Resources