如何使用 DataTrigger 更改 ItemsControl 中的 ItemsPanel?

How to change ItemsPanel in ItemsControl with DataTrigger?

我试图制作一个包含多个元素的 UserControl,当单击按钮时,该控件将内部元素布局从垂直更改为水平。

我在 ItemsControl 模板中放置了一个布局更改 ToggleButton。我还创建了一个带有触发器的样式,它应该通过更改 ItemsControl 中的 ItemsPanel 来更改项目的位置。此外,触发器更改 ItemsControl 的背景。

<ItemsControl.Template>
  <ControlTemplate TargetType="ItemsControl">
     <Grid>
        <Grid.Style>
            <Style TargetType="Grid">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding ElementName=HideShowButton, Path=IsChecked}" Value="True">
                        <DataTrigger.Setters>
                            <Setter Property="ItemsControl.Background" Value="LightGreen"/>
                            <Setter Property="ItemsControl.ItemsPanel" Value="{DynamicResource HorizontalPanelTemplate}"/>
                        </DataTrigger.Setters>
                    </DataTrigger>

                    <DataTrigger Binding="{Binding ElementName=HideShowButton, Path=IsChecked}" Value="False">
                        <DataTrigger.Setters>
                            <Setter Property="ItemsControl.Background" Value="LightBlue"/>
                            <Setter Property="ItemsControl.ItemsPanel" Value="{DynamicResource VerticalPanelTemplate}"/>
                        </DataTrigger.Setters>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Grid.Style>

        <Grid.RowDefinitions>
            <RowDefinition x:Name="HeaderRow" Height="*"/>
            <RowDefinition x:Name="ToggleRow" Height="50"/>
        </Grid.RowDefinitions>

        <ItemsPresenter x:Name="ItemsPresenter" Grid.Row="0"/>

        <ToggleButton x:Name="HideShowButton" Grid.Row="1"
                                      Content="Change"
                                      VerticalAlignment="Center" HorizontalAlignment="Right"
                                      Margin="5"/>
     </Grid>
  </ControlTemplate>
</ItemsControl.Template>

因此,触发器有效,颜色切换,但元素的排列始终保持不变。

我尝试按照文章中所述通过 GroupStyle 进行操作:https://social.msdn.microsoft.com/Forums/vstudio/en-US/b0ecb187-134e-4868-b56e-b67fb5ad18ff/itemscontrol-with-groupstyle-how-to-dynamically-switch-itemspanel?forum=wpf 但失败了,外观没有改变。

完整的用户控件代码

    <UserControl x:Class="HeaderControlDemo.HeaderControl"
             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" 
             d:DesignHeight="450" d:DesignWidth="800">
    <UserControl.Template>
        <ControlTemplate>
            <ItemsControl x:Name="ItemsControl" Margin="{TemplateBinding Padding}"
                          ItemsSource="{Binding Path=HeaderItems}">
                <ItemsControl.Resources>
                    <ItemsPanelTemplate x:Key="HorizontalPanelTemplate">
                        <StackPanel Orientation="Horizontal"/>
                    </ItemsPanelTemplate>

                    <ItemsPanelTemplate x:Key="VerticalPanelTemplate">
                        <StackPanel Orientation="Vertical"/>
                    </ItemsPanelTemplate>
                </ItemsControl.Resources>

                <ItemsControl.Template>
                    <ControlTemplate TargetType="ItemsControl">
                        <Grid>
                            <Grid.Style>
                                <Style TargetType="Grid">
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding ElementName=HideShowButton, Path=IsChecked}" Value="True">
                                            <DataTrigger.Setters>
                                                <Setter Property="ItemsControl.Background" Value="LightGreen"/>
                                                <Setter Property="ItemsControl.ItemsPanel" Value="{DynamicResource HorizontalPanelTemplate}"/>
                                            </DataTrigger.Setters>
                                        </DataTrigger>

                                        <DataTrigger Binding="{Binding ElementName=HideShowButton, Path=IsChecked}" Value="False">
                                            <DataTrigger.Setters>
                                                <Setter Property="ItemsControl.Background" Value="LightBlue"/>
                                                <Setter Property="ItemsControl.ItemsPanel" Value="{DynamicResource VerticalPanelTemplate}"/>
                                            </DataTrigger.Setters>
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </Grid.Style>

                            <Grid.RowDefinitions>
                                <RowDefinition x:Name="HeaderRow" Height="*"/>
                                <RowDefinition x:Name="ToggleRow" Height="50"/>
                            </Grid.RowDefinitions>

                            <ItemsPresenter x:Name="ItemsPresenter" Grid.Row="0"/>

                            <ToggleButton x:Name="HideShowButton" Grid.Row="1"
                                          Content="Change"
                                          VerticalAlignment="Center" HorizontalAlignment="Right"
                                          Margin="5"/>
                        </Grid>
                    </ControlTemplate>
                </ItemsControl.Template>

                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Grid VerticalAlignment="Top" HorizontalAlignment="Left"
                              Background="Gray">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="30"/>
                                <RowDefinition Height="*"/>
                            </Grid.RowDefinitions>

                            <TextBlock Grid.Row="0" 
                                       HorizontalAlignment="Center" VerticalAlignment="Center"
                                       Text="Header"/>
                            <Border Grid.Row="1" 
                                    HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                                    Padding="5"
                                    Background="LightGray">
                                <ContentControl>
                                    <ContentControl.ContentTemplate>
                                        <DataTemplate>
                                            <TextBox DataContext="{Binding RelativeSource={RelativeSource AncestorType=ContentControl}, Path=DataContext}" 
                                                     Text="{Binding Path=PropertyValue, UpdateSourceTrigger=PropertyChanged}"
                                                     FontSize="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=FontSize}"
                                                     FontFamily="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=FontFamily}"
                                                     VerticalAlignment="Top"
                                                     Background="White"/>
                                        </DataTemplate>
                                    </ContentControl.ContentTemplate>
                                </ContentControl>
                            </Border>
                        </Grid>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </ControlTemplate>
    </UserControl.Template>
</UserControl>

您可以使用 DataTrigger 更改用作 ItemsPanel 的 StackPanel 的方向:

<ItemsControl ItemsSource="{Binding}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel>
                <StackPanel.Style>
                    <Style TargetType="StackPanel">
                        <Style.Triggers>
                            <DataTrigger
                                Binding="{Binding IsChecked, ElementName=tb}"
                                Value="True">
                                <Setter Property="Orientation" Value="Horizontal"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </StackPanel.Style>
            </StackPanel>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

<ToggleButton x:Name="tb" Content=" Horizontal "/>