如何从VisualState更改模板化控件的属性?

时间:2013-04-12 01:14:30

标签: c# wpf xaml visualstates

如果我在控件模板中定义VisualStates,是否可以从故事板中更改模板化控件本身的属性?这是一个简单的例子:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Window.Template>
    <ControlTemplate TargetType="{x:Type Window}">
      <Grid>
        <VisualStateManager.VisualStateGroups>
          <VisualStateGroup x:Name="WindowStyleStates"
                            x:Uid="WindowStyleStates">
            <Storyboard x:Uid="Storyboard_1">
              <ObjectAnimationUsingKeyFrames Storyboard.TargetName="?????"
                                             Storyboard.TargetProperty="ResizeMode">
                <DiscreteObjectKeyFrame KeyTime="0"
                                        Value="CanResizeWithGrip" />
              </ObjectAnimationUsingKeyFrames>
            </Storyboard>
          </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
      </Grid>
    </ControlTemplate>
  </Window.Template>
</Window>

问题是故事板只能访问网格中定义的对象。如果我正在为一个Window定义一个controltemplate,为什么我不能在我正在模板化的Window上更改值。

1 个答案:

答案 0 :(得分:1)

您无需ControlTemplate即可访问VisualStateManager。这应该可以解决问题,虽然我没有尝试过。

<Window x:Name="YourWindow" ...>
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="WindowStyleStates" x:Uid="WindowStyleStates">
            <Storyboard x:Uid="Storyboard_1">
                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="YourWindow"
                                               Storyboard.TargetProperty="ResizeMode">
                    <DiscreteObjectKeyFrame KeyTime="0" Value="CanResizeWithGrip"/>
                </ObjectAnimationUsingKeyFrames>
            </Storyboard>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
</Window>

但是代码背后的VisualStateManager.GoToState(...)似乎存在问题,至少对于.Net 3.5而言。但是有一个workaround。我不知道这对你来说是否重要。

回答标题中的问题:我认为您错过了控件模板背后的概念。一个小例子......

<!-- A simple button with round corners -->
<Button>
  <Button.Template>
    <ControlTemplate>
      <Border x:Name="ButtonBorder"
              CornerRadius="10"
              BorderBrush="{TemplateBinding BorderBrush}"
              BorderThickness="{TemplateBinding BorderThickness}">
        <Grid>
          <ContentPresenter x:Name="ButtonContent"
                            Content="{TemplateBinding Content}" />
          <Border x:Name="ButtonBackground"
                  Background="{TemplateBinding Background}"
                  BorderBrush="{x:Null}"
                  BorderThickness="0" />
        </Grid>
      </Border>
    </ControlTemplate>
  </Button.Template>
</Button>

如您所见,模板为Button提供了新的外观。此外,视觉行为也被覆盖。在这种情况下,没有视觉行为,虽然按钮将按预期工作 要定义可视行为,您可以使用VisualStateManager和预定义状态或自定义状态。但是,您只能修改模板中的元素是合理的,因为您要重新实现按钮的外观。因此,您需要将VisualStateManager添加到 ButtonBorder