Silverlight& WPF:ControlTemplate中的VisualStateManager不起作用

时间:2011-06-01 13:46:14

标签: wpf silverlight controltemplate visualstatemanager

所以,大家好。

我已经制作了两个用于创建自己控件的测试程序。一个在Silverlight中,一个在WPF中。我创建了一种RangeSlider。这个滑块当然有两个方向,水平和垂直。 首先,我使用两种不同的技术来创建RangeSlider。在WPF中,我在Silverlight中使用了触发器(你知道没有触发器)我在CodeBehind中改变了水平和垂直模板的可见性。这就运行了。

现在: 我正在尝试使用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的视觉效果是由模板定义的,这里是Horizo​​ntalSliderTemplate(我再次减少代码):

<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”访问元素? 或者“内部”模板中的VSM无法访问?

我希望我能够很好地解释我的问题并且有人知道解决方案或关键字我能找到的东西。只需在谷歌中输入关键字VSM,ControlTemplate,Storyboard等就无济于事。

提前致谢。

2 个答案:

答案 0 :(得分:0)

我认为你不能在一个ControlTemplate中拥有多个VSM。

为什么不用一个VSM来切换它们。

<ControlTemplate>
  <Grid x:Name="PART_Content">
    <Grid x:Name="PART_HorizontalTemplate">
      ...
    </Grid>
    <Grid x:Name="PART_VerticalTemplate">
      ...
    </Grid>
<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">
<Storyboard>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_VerticalTemplate"
                                       Storyboard.TargetProperty="Visibility">
          <DiscreteObjectKeyFrame Value="{x:Static Visibility.Collapsed}" KeyTime="0"/>
        </ObjectAnimationUsingKeyFrames>
      </Storyboard>
    </VisualState>
  </VisualStateGroup>
</VisualStateManager.VisualStateGroups>
  </Grid>
</ControlTemplate>

答案 1 :(得分:0)

所以,我得到了一个解决方案。 在“内部”模板中,我添加到要切换DataTrigger的元素中。此DataTrigger绑定到PART_Horizo​​ntalTemplate可见性,并包含一个可以执行我需要的操作的Storyboard。

也许这不是我想要的那种解决方案,因为它会大量延伸代码并使其看起来更复杂。但是 - 这是最重要的 - 它运行良好。