如何使用 DataTrigger 更改 ItemsControl 中的 ItemsPanel?
Posted
技术标签:
【中文标题】如何使用 DataTrigger 更改 ItemsControl 中的 ItemsPanel?【英文标题】:How to change ItemsPanel in ItemsControl with DataTrigger? 【发布时间】:2021-11-22 09:07:18 【问题描述】:我试图制作一个包含多个元素的 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>
【问题讨论】:
【参考方案1】:您可以使用 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 "/>
【讨论】:
以上是关于如何使用 DataTrigger 更改 ItemsControl 中的 ItemsPanel?的主要内容,如果未能解决你的问题,请参考以下文章
Datatrigger 适当地改变了 TextBlock 的初始属性,但不是在对象改变之后
如何使用 Binding="Binding" 以编程方式创建 DataTrigger?
如何将触发器与 SourceName 和 DataTrigger 结合使用?