I have this xaml
code in a View
<StackPanel>
<Button Content="I am IRON" />
<ListView ItemsSource="{Binding Path=MeasuringDeviceCommunicators}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
The ItemSource
of the ListView
is bound to a List
in my ViewModel
(as shown in the code)
When I run the application all my TextBlocks
are shown vertically even though I have set the Orientation
of the inner StackPanel to Horizontal
.
This is because StackPanel measures in the direction of stacking at PositiveInfinity, whereas DockPanel measures only the available size. The following example demonstrates this key difference. The difference in rendering behavior can be seen in this image.
A StackPanel allows you to stack elements in a specified direction. By using properties that are defined on StackPanel, content can flow both vertically, which is the default setting, or horizontally.
StackPanel is a layout panel that arranges child elements into a single line that can be oriented horizontally or vertically. By default, StackPanel stacks items vertically from top to bottom in the order they are declared. You can set the Orientation property to Horizontal to stack items from left to right.
WPF WrapPanel control is a panel that positions child elements in sequential position from left to right by default. If child elements that are stacked don't fit in the row or column they are in, the remaining elements will wrap around in the same sequence.
To change the layout of a ListView
, use the ItemsControl.ItemsPanel
property:
<StackPanel>
<Button Content="I am IRON" />
<ListView ItemsSource="{Binding Path=MeasuringDeviceCommunicators}" >
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<!-- Here is the panel that will contain the items -->
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<!-- Your item Template is here -->
<TextBlock Text="{Binding Path=Name}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
You also may want to use a VirtualizingStackPanel
instead of StackPanel
, it may improve performance (if you have lot of items to show).
If you want to add a list in each item of your stack panel, you can do it by modifying the ItemTemplate
(which represents how each item is displayed).
For example:
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="8"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Path=Name}"/>
<!-- Displays the tags (or whatever you want) -->
<ListView Grid.Column="2" ItemsSource="{Binding Tags}"/>
<Grid>
</DataTemplate>
</ListView.ItemTemplate>
To sum up, the ListView
has 3 interesting properties to define how it is rendered:
ItemsControl.ItemTemplate
: Represents how the items in the list are renderedItemsControl.ItemsPanel
: Represents the layout of the list (the position and size of the items in the list). You can use StackPanel
, VirtualizingStackPanel
, WrapPanel
, ... Control.Template
: Represents how the whole list is renderedHere is a code using all these properties:
<ListView>
<ListView.Items>
<Button Content="Button 1"/>
<Button Content="Button 2"/>
<Button Content="Button 3"/>
<Button Content="Button 4"/>
</ListView.Items>
<!-- The layout of the list (position and size of the elements -->
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<!-- StackPanel means : the elements are rendered in stack, either horizontally or vertically (the way it is rendered in StackPanel is defined in code -->
<StackPanel Orientation="Vertical" Background="LightCoral"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<!-- How I want the list to look like? -->
<ListView.Template>
<ControlTemplate>
<!-- A blue background with a green border -->
<Border Background="LightBlue" BorderBrush="DarkGreen" BorderThickness="5">
<!-- ItemsPresenter "represents" the ItemsPanel defined above -->
<ItemsPresenter HorizontalAlignment="Right" />
</Border>
</ControlTemplate>
</ListView.Template>
<!-- How I want each item to look like? -->
<ListView.ItemTemplate>
<DataTemplate>
<!-- A "This is an item:" label followed by the item itself -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="8"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="This is an item : "/>
<ContentPresenter Grid.Column="2" Content="{Binding}"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Note, this part:
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" Background="LightCoral"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.Template>
<ControlTemplate>
<Border Background="LightBlue" BorderBrush="DarkGreen" BorderThickness="5">
<ItemsPresenter HorizontalAlignment="Right" />
</Border>
</ControlTemplate>
</ListView.Template>
is equivalent to:
<ListView.Template>
<ControlTemplate>
<Border Background="LightBlue" BorderBrush="DarkGreen" BorderThickness="5">
<StackPanel Orientation="Vertical" Background="LightCoral"
HorizontalAlignment="Right"
IsItemsHost="True"/>
</Border>
</ControlTemplate>
</ListView.Template>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With