如何在代码中动态地向自定义控件模板添加新的可视状态?

5

在代码中,是否有可能通过编程的方式向自定义控件模板的VisualStateManager添加一个新的VisualState?
例如,在设计时,我可以手动将以下XAML添加到CustomControl模板中:

<VisualState x:Name="First">
   <Storyboard>
      <ColorAnimation Duration="0:0:0"
                      Storyboard.TargetName="SBorder"
                      Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)" To="Red" />
    </Storyboard>
</VisualState>

但是我该如何在运行时添加一个新的VisualState呢?

2个回答

2
我认为这是可行的,但绝不容易...
这应该可以运行:
Grid grid = this.Template.FindName("RootElement", this) as Grid;
(VisualStateManager.GetVisualStateGroups(grid)).Add(new VisualStateGroup() { /* the code for your visualstategroup here */ });

你需要根据模板根元素的名称和设置VisualStateManager的位置进行调整,但总的来说这可以起作用。

此外,这还添加了一个新的visualStateGroup,而不仅仅是一个visualState。如果您想将VisualState添加到现有的visualStateGroup中,您需要先从集合中获取组,但这是常见的“从集合获取元素”操作。

基本上:

  1. 获取包含visualStateManager的模板元素
  2. 使用VisualStateManager.GetVisualStateGroups()静态方法获取当前的visualStateGroups
  3. 从集合中获取您想要的组或创建一个新组并将其添加到集合中
  4. 在此组中添加一个新的visualState

希望这可以帮助到您。


1
你应该使用XAML创建组本身,然后按照以下方式查找你要查找的VisualStateGroup:
VisualStateGroup visualStateGroupLookingFor = null;
var visualStateGroups = (VisualStateManager.GetVisualStateGroups(LayoutRoot));
foreach (VisualStateGroup state in visualStateGroups) {
    if (state.Name == "VisualStateGroupMine") {
        visualStateGroupLookingFor = state;
        break;
        }
    }

然后,您需要创建一个新的VisualState和Storyboard来添加,例如:

var visualState = new VisualState();
var storyBoard = new Storyboard();

现在,创建动画:
var animation = new DoubleAnimation();
animation.To = 10.0;

并设置动画的目标:
//assuming this is instance of class ClassFoo
//and you want to animate it's Width
Storyboard.SetTarget(animation, this);
Storyboard.SetTargetProperty(animation, new PropertyPath(ClassFoo.WidthProperty));

最后将动画添加到你的故事板中,给它一个名称,并将其添加到visualstategroup中:
storyBoard.Children.Add(animation);
visualState.Storyboard = storyBoard;
visualState.Name = "CoolNameLikeWidthAnimation";
visualStateGroupLookingFor.States.Add(visualState);

就这样,像往常一样触发它

VisualStateManager.GoToState(this, "CoolNameLikeWidthAnimation", true);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接