【发布时间】:2011-03-11 00:04:24
【问题描述】:
我想制作一个带有环绕面板行为和可调整大小控件的网格,我该怎么做? 也许在图像中显示我想要的内容更容易:
初始状态:
使用右下角调整控件 1 的大小,使其占用大约 2x2 个单元格,然后控件 2 等将重新排列它在网格上的位置:
当它重新调整大小时,它应该回到初始状态。
【问题讨论】:
标签: wpf grid resizable wrappanel
我想制作一个带有环绕面板行为和可调整大小控件的网格,我该怎么做? 也许在图像中显示我想要的内容更容易:
初始状态:
使用右下角调整控件 1 的大小,使其占用大约 2x2 个单元格,然后控件 2 等将重新排列它在网格上的位置:
当它重新调整大小时,它应该回到初始状态。
【问题讨论】:
标签: wpf grid resizable wrappanel
您只需要创建一个扩展 Panel 的类来创建动画。这是关于如何创建动画WrapPanel 的very good article。然后,您需要为使用Triggers 来扩大和缩小每个项目的项目创建一个DataTemplate。这也可以在Trigger 中进行动画处理。 Panel 会随着项目大小的变化自动移动其他项目...取决于您在 Panel.ArrangeOverride 方法中输入的代码。
您需要创建一个数据类型(类)以用作您的项目(正方形)。这个类需要一个字符串属性来存储盒子编号和一个bool IsLarge 属性来让 UI 知道是否将其显示为大。我实际上并没有尝试过这段代码,但你可以为你的DataTemplate 使用类似的代码:
<DataTemplate DataType="{x:Type YourXmlNameSpace:YourDataType}" x:Key="BoxTemplate">
<Border Name="Border" BorderBrush="Black" BorderThickness="1" CornerRadius="3" Height="100" Width="100">
<TextBlock Text="{Binding YourTextProperty}" />
</Border>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsLarge}" Value="True"><!-- (A Boolean property) -->
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="Border" Storyboard.TargetProperty="Height" From="100" To="200" Duration="0:0:0.5" />
<DoubleAnimation Storyboard.TargetName="Border" Storyboard.TargetProperty="Width" From="100" To="200" Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="Border" Storyboard.TargetProperty="Height" From="200" To="100" Duration="0:0:0.5" />
<DoubleAnimation Storyboard.TargetName="Border" Storyboard.TargetProperty="Width" From="200" To="100" Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
然后你将DataTemplate 与每个ListBoxItem 关联起来,如下所示:
<Style TargetType="{x:Type ListBoxItem}" x:Key="BoxStyle">
<Setter Property="ContentTemplate" Value="{StaticResource BoxTemplate}" />
<Style.Resources><!-- this removes the default blue selection colour -->
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="#00FFFAB0" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="#00FFFAB0" />
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="Black" />
</Style.Resources>
<Style.Triggers><!-- comment this section out, or declare a SelectedBoxTemplate DataTemplate -->
<Trigger Property="IsSelected" Value="True">
<Setter Property="ContentTemplate" Value="{StaticResource SelectedBoxTemplate}" />
</Trigger>
</Style.Triggers>
</Style>
我还没有定义任何SelectedBoxTemplateDataTemplate,但您可以声明一个不同的可以使用Style.Trigger 激活的。
最后,你可以像这样声明你的ListBox:
<ListBox ItemsSource="{Binding YourCollection}" ItemContainerStyle="{StaticResource BoxStyle}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<YourXmlNameSpace:YourAnimationPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
【讨论】:
Panel.MeasureOverride 和 Panel.ArrangeOverride 方法中的代码。您的代码最终应该与示例中的代码非常相似,尽管它会稍微复杂一些。示例代码使用最大的child.DesiredSize.Height 来确定每一行的高度,但您必须在此处做更多工作,以确保每行可以有两个小框,其中有一个大框。