Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make a StackPanel Orientation Horizontal in WPF

Tags:

c#

wpf

xaml

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.

like image 632
Mehrdad Kamelzadeh Avatar asked Jul 28 '13 13:07

Mehrdad Kamelzadeh


People also ask

What is the difference between StackPanel and DockPanel?

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.

What is the use of StackPanel in WPF?

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.

What is StackPanel in UWP?

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.

What is wrap panel WPF?

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.


1 Answers

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

Update

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 rendered
  • ItemsControl.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 rendered

Here 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>
like image 177
Cédric Bignon Avatar answered Oct 12 '22 13:10

Cédric Bignon