Search code examples
c#wpfwrappanel

WrapPanel doesnt wrap horizontal with DataTemplate


I'm filling a two WrapPanel with Buttons via DataTemplate but they all align vertically for some reason, what exactly is wrong here? It doesn't matter if I set the Orientation property or not.

XAML:

<UserControl x:Class="DashboardClient.View.DashboardView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d"
             Width="940" Height="640">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="400" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <DockPanel Grid.Column="0"  Height="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Grid}},Path=ActualHeight}">
            <ScrollViewer VerticalScrollBarVisibility="Auto" DockPanel.Dock="Top" Height="520" Margin="5">
                <WrapPanel>
                    <ItemsControl ItemsSource="{Binding Dashboards}">
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <Button Width="120" Height="120" Margin="5" Command="{Binding DataContext.DashboardCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}" CommandParameter="{Binding}">
                                    <TextBlock TextWrapping="Wrap" HorizontalAlignment="Center" Text="{Binding Name}" />
                                </Button>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>
                    <Button Width="120" Height="120" Margin="5" Command="{Binding DashboardAddCommand}" Content="+" FontSize="100" />
                </WrapPanel>
            </ScrollViewer>
            <StackPanel Height="100" Margin="5">
                <Label>Dashboardname:</Label>
                <TextBox Text="{Binding SelectedDashboard.Name}" />
                <RadioButton Content="Sichtbar" Margin="0 10" IsChecked="{Binding SelectedDashboard.IsVisibleOnDashboard, UpdateSourceTrigger=PropertyChanged}" />
                <Button Content="Dashboard löschen" Command="{Binding DashboardRemoveCommand}" />
            </StackPanel>
        </DockPanel>
        <StackPanel Grid.Column="1" Margin="0">
            <ScrollViewer VerticalScrollBarVisibility="Auto" Height="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type StackPanel}},Path=ActualHeight}">
                <WrapPanel>
                    <ItemsControl ItemsSource="{Binding SelectedDashboard.DashboardItems}">
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <Button Width="200" Height="120" Command="{Binding DataContext.DashboardItemCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}" CommandParameter="{Binding}" Margin="10">
                                    <TextBlock TextWrapping="Wrap" HorizontalAlignment="Center" Text="{Binding Name}" />
                                </Button>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>
                    <Button Width="200" Height="120" Content="+" FontSize="100" Command="{Binding DashboardItemAddCommand}" Margin="10" />
                </WrapPanel>
            </ScrollViewer>
        </StackPanel>
    </Grid>
</UserControl>

This is what the WrapPanel looks like:
Image of the WrapPanel

The Add Button is always cut off somehow, too.


Solution

  • If you want to put the children of the ItemsControl horizontally in a WrapPanel, you need to tell the ItemsControl to use a WrapPanel for its children via an ItemsPanelTemplate:

    <WrapPanel Orientation="Horizontal">
        <ItemsControl ItemsSource="{Binding Dashboards}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Button 
                        Width="120" 
                        Height="120" 
                        Margin="5" 
                        Command="{Binding DataContext.DashboardCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}" 
                        CommandParameter="{Binding}"
                        >
                        <TextBlock 
                            TextWrapping="Wrap" 
                            HorizontalAlignment="Center" 
                            Text="{Binding Name}" 
                            />
                    </Button>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
        <Button 
            Width="120" 
            Height="120" 
            Margin="5" 
            VerticalAlignment="Top"
            Command="{Binding DashboardAddCommand}" 
            Content="+" 
            FontSize="100" 
            />
    </WrapPanel>
    

    I don't know what you want to do with the button. My guess is that you want it to the right of the ItemsControl, and I aligned it to the top because that makes more sense to me.