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

本文关键字:控件 属性 VisualState | 更新日期: 2023-09-27 18:08:59

如果我从控件模板中定义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>

问题是故事板只能访问网格中定义的对象。如果我为一个窗口定义一个控件模板,为什么我不能改变我正在模板的窗口上的值。

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

您不需要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。但有一个变通办法。我不知道这对你是否重要。

回答你标题中的问题:我认为你误解了控件模板背后的概念。一个小例子…

<!-- 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和预定义状态或自定义状态。但是您只能修改模板中的元素,这是合理的,因为您希望重新实现按钮的外观和感觉。因此,您可以添加VisualStateManagerButtonBorder