WPF VisualStateManager - 如何为模板化子项内的属性设置动画
我有一个 UserControl,其中包含一个具有自定义 ItemsPanel 的 ItemsControl,其依赖属性名为“MaxColumns”。我想定义一个 VisualState(在 UserControl 级别),它可以为自定义面板上的“MaxColumns”属性设置动画。
本质上,XAML 看起来像:
<Grid x:Name="LayoutRoot">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="MyCoolState">
<VisualState x:Name="Normal" />
<VisualState x:Name="NotNormal">
<Storyboard>
<Int32Animation Duration="0"
Storyboard.TargetName="Details"
Storyboard.TargetProperty="(ItemsControl.ItemsPanel).(local:CoolPanel.MaxColumns)"
To="4" />
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateManager>
<ItemsControl x:Name="Details">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<local:CoolPanel x:Name="MyCoolPanel"
MaxColumns="1" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
但是,我一辈子都无法弄清楚动画的正确语法是什么?如果我使用上面显示的语法,则会收到错误:“'ItemsPanel' 属性未指向路径 '(0).(1)' 中的 DependencyObject”。我认为这是因为它在技术上指向 ItemsPanelTemplate?
如果我直接在 Storyboard.TargetName 属性中引用“MyCoolPanel”,则会收到有关名称范围的错误(可能是因为“MyCoolPanel”不在 LayoutRoot 的名称范围内)。我不知道是否有办法限定“TargetName”中的名称范围?
有人有解决方案吗?看起来应该可以在不诉诸自定义附加属性的情况下完成?我的意思是,我并不反对附加属性,但我觉得您应该能够直接在 XAML 中执行此操作?
I have a UserControl that contains an ItemsControl with a custom ItemsPanel, with a dependency property called "MaxColumns". I'd like to define a VisualState (at the UserControl level) that can animate the "MaxColumns" property on the custom panel.
In essence, the XAML looks something like:
<Grid x:Name="LayoutRoot">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="MyCoolState">
<VisualState x:Name="Normal" />
<VisualState x:Name="NotNormal">
<Storyboard>
<Int32Animation Duration="0"
Storyboard.TargetName="Details"
Storyboard.TargetProperty="(ItemsControl.ItemsPanel).(local:CoolPanel.MaxColumns)"
To="4" />
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateManager>
<ItemsControl x:Name="Details">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<local:CoolPanel x:Name="MyCoolPanel"
MaxColumns="1" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
However, I cannot for the life of me figure out what the right syntax is for the animation? If I use the syntax shown above, I get the error: "'ItemsPanel' property does not point to a DependencyObject in path '(0).(1)'". I'm presuming this is because it's technically pointing to a ItemsPanelTemplate?
If I refer to "MyCoolPanel" directly in the Storyboard.TargetName property, I get an error about Name scope (presumably because "MyCoolPanel" isn't in the namescope of LayoutRoot). I don't know if there is a way to qualify name scope in "TargetName"?
Does anyone have a solution for this? It seems like something that should be doable without resorting to custom attached properties? I mean, I'm not opposed to attached properties, but I feel like you ought to be able to do this directly in the XAML?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好吧,事实上
ItemsPanel
不是一个真实的对象,而是一个用于创建该对象的模板。所以从技术上讲,你的参考是行不通的。我有以下关于实现的信息:
RelativeSource FindAncestor
将CoolPanel
的 MaxColumns 绑定到该附加属性。好吧,您可以省略附加属性,并使用
Tag
:-) 事实上,ItemsControl
完全在您的控制之下,因此滥用Tag
并不构成犯罪。 code>Tag 一点点。所以代码会是这样的:
Okay, indeed the
ItemsPanel
is not a real object but a template with which the object is going to be created. So technically your reference is not going to work.I've got the following about implementation:
CoolPanel
's MaxColumns to that attached property usingRelativeSource FindAncestor
.Well, you could omit the attached property, and use
Tag
for it :-) Indeed, theItemsControl
is totally in your control, so there is no crime in abusing theTag
a little bit.So the code would be like this: