WrapPanel 不使用 DataTemplate 水平换行

WrapPanel doesnt wrap horizontal with DataTemplate

我正在通过 DataTemplate 填充带有按钮的两个 WrapPanel,但由于某种原因它们都垂直对齐,这里到底有什么问题? 我是否设置 Orientation 属性 并不重要。

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>

WrapPanel 的外观如下:

添加按钮也总是以某种方式被切断。

如果要将 ItemsControl 的子项水平放置在 WrapPanel 中,则需要通过 ItemsPanelTemplate 告诉 ItemsControl 对其子项使用 WrapPanel:

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

我不知道你想用这个按钮做什么。我的猜测是您希望它位于 ItemsControl 的右侧,而我将它对齐到顶部,因为这对我来说更有意义。

而不是

<ScrollViewer>
    <WrapPanel>
        <ItemsControl ItemsSource="{Binding Dashboards}">
            <ItemsControl.ItemTemplate ... />
        </ItemsControl>
        <Button Content="+" ... />
    </WrapPanel>
</ScrollViewer>

你可以使用

<ScrollViewer>
    <ItemsControl ItemsSource="{Binding Dashboards}">
        <ItemsControl.ItemTemplate ... />
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
    <Button Content="+" ... /> <!-- A -->
</ScrollViewer>
<Button Content="+" ... /> <!-- B -->

WrapPanel 已移至 内部 ItemsControl 布局仪表板。

你可以把按钮放在其他地方(和@EdPlunkett一样,我不知道放在哪里):A - 会让你滚动按钮与仪表板一起,B 将保持按钮固定,忽略滚动。