银光与WPF:ControlTemplate 中的 VisualStateManager 不起作用
那么,大家好。
我制作了两个测试程序来创建自己的控件。一种在 Silverlight 中,一种在 WPF 中。我创建了一种 RangeSlider。该滑块当然有两个方向:水平和垂直。 首先,我使用两种不同的技术来创建 RangeSlider。在 WPF 中我使用了触发器,在 Silverlight 中(你知道没有触发器)我更改了 CodeBehind.This 运行中水平和垂直模板的可见性。
现在: 我正在尝试对 Silverlight 和 WPF 使用一种技术。因此我使用 VisualStateManager。
我有一个定义两个滑块的模板(一个用于左值,另一个用于右值)。重要值的简化如下所示:
...
<ControlTemplate>
<Grid x:Name="PART_Content">
<!-- VSM: See following code sequence -->
<Grid x:Name="PART_HorizontalTemplate">
<Slider x:Name="PART_HorizontalSliderLeft"
Template="{StaticResource HorizontalSliderTemplate}"
Orientation="{TemplateBinding Orientation}" />
...
</Grid>
<Grid x:Name="PART_VerticalTemplate">
...
</Grid>
</Grid>
</ControlTemplate>
另外,还有 VSM 可在水平和垂直外观之间切换:
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="Vertical">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_HorizontalTemplate"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame Value="{x:Static Visibility.Collapsed}" KeyTime="0"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Horizontal" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
这仍然运行。
正如您在代码序列中看到的,Slider的视觉是由一个Template定义的,这里是HorizontalSliderTemplate(我再次减少代码):
<ControlTemplate x:Key="HorizontalSliderTemplate" TargetType="{x:Type Slider}">
<Border x:Name="Border" ...>
<!-- VSM here. Like above. -->
<Grid x:Name="Grid">
<Rectangle x:Name="PART_SelectionRange"/>
<Track x:Name="PART_Track">
...
</Track>
</Grid>
</Border>
</ControlTemplate>
实际上还有一个VerticalSliderTemplate。 但我想将两个 ControlTemplate 合并在一个模板中并使用 VSM。这里我们遇到了我的问题:
我无法在“内部”ControlTemplate 中运行 VSM。它与正在运行的 VSM-Part 的代码几乎相同,只是 TargetName 发生了变化。我不知道如何调试 GoToState 上运行的内容,但我相信模板中的 VSM 永远不会被发现,并且永远不会执行。
我可以想象,只是缺少了一点细节,但我“只见树木,不见森林”。也许有一些关于模板或 VSM 的重要事情我不知道,而且我偏离了轨道。 或者我是否必须从外部触发“内部”VSM,或者有可能从“外部 VSM”访问 Elements? 或者“内部”模板中无法访问 VSM?
我希望我能足够好地解释我的问题,并且有人知道解决方案或者我可以寻找的关键字。仅在谷歌中输入关键字VSM、ControlTemplate、Storyboard等没有任何帮助。
提前致谢。
So, hello everybody.
I've made two test programs for creating a own control. One in Silverlight, one in WPF. I created a kind of RangeSlider. This Slider has of course two Orientations, Horizontal and Vertical.
First I used two different techniques to create my RangeSlider. In WPF I used Triggers, in Silverlight (u know there arent Triggers) I changed the Visibility of the Horizontal and Vertical Template in CodeBehind.This runs.
Now:
I'm trying to use one technique for both, Silverlight and WPF. Therefore I use VisualStateManager.
I've a Template defining two Sliders (one for left value, the other for right value). Simplified on the important values it looks like that:
...
<ControlTemplate>
<Grid x:Name="PART_Content">
<!-- VSM: See following code sequence -->
<Grid x:Name="PART_HorizontalTemplate">
<Slider x:Name="PART_HorizontalSliderLeft"
Template="{StaticResource HorizontalSliderTemplate}"
Orientation="{TemplateBinding Orientation}" />
...
</Grid>
<Grid x:Name="PART_VerticalTemplate">
...
</Grid>
</Grid>
</ControlTemplate>
Additionally there is the VSM to switch between Horizontal and Vertical look:
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="Vertical">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_HorizontalTemplate"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame Value="{x:Static Visibility.Collapsed}" KeyTime="0"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Horizontal" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
This still runs.
As you see in the code sequence, the visual of Slider is defined by a Template, here HorizontalSliderTemplate (I reduce code again):
<ControlTemplate x:Key="HorizontalSliderTemplate" TargetType="{x:Type Slider}">
<Border x:Name="Border" ...>
<!-- VSM here. Like above. -->
<Grid x:Name="Grid">
<Rectangle x:Name="PART_SelectionRange"/>
<Track x:Name="PART_Track">
...
</Track>
</Grid>
</Border>
</ControlTemplate>
Actually there is also a VerticalSliderTemplate.
But I want to combine both ControlTemplate in one Template and use VSM. Here we come to my problem:
I do not get running the VSM in the 'inner' ControlTemplate. It's nearly the same code as the running VSM-Part, just the TargetName is changed. I do not know how to debug what's running on GoToState, but I believe the VSM in the template is never found and from there never execute.
I can imagine that there's just a little detail missing, but I 'cant see the wood for the trees'. Maybe there is an important thing what I do not know about Templates or about VSM, and I'm off the track.
Or do I have to trigger the 'inner' VSM from outside, or there's a possibility to access onto Elements from 'outside VSM'?
Or is there no access on VSM in 'inner' Templates?
I hope I could explain my problem good enough and there is someone, who knows a solution or maybe a keyword what I can look for. Just entering keywords VSM, ControlTemplate, Storyboard, etc. in google gives no helping hand.
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为一个 ControlTemplate 中不能有多个 VSM。
为什么不只使用一个 VSM 来切换两者呢?
I don't think you can have multiple VSMs inside one ControlTemplate.
Why don't you just use one VSM to toggle both.
所以,我得到了一个解决方案。
在“内部”模板中,我添加了要切换 DataTrigger 的元素。此 DataTrigger 绑定到 PART_HorizontalTemplate Visibility,并包含执行我需要的操作的 Storyboard。
也许这并不是我真正想要的那种解决方案,因为它大大扩展了代码并使其看起来更复杂。但是 - 这是最重要的 - 它运行良好。
So, I got a solution on it.
In the 'inner' template I added to the element I want to toggle a DataTrigger. This DataTrigger is bound to the PART_HorizontalTemplate Visibility and contains a Storyboard that do the action I need.
Maybe it's not really the kind of solution I was looking for, because it stretches the code a lot and makes it therefore looking more complex. But - and thats most important - it runs well.