如何在代码中动态地将新的Visual States添加到自定义控件模板?

时间:2011-03-06 20:30:36

标签: c# wpf silverlight custom-controls visualstatemanager

是否可以在代码中以编程方式将新VisualState添加到 CustomControl模板VisualStateManager
例如,我可以在设计时手动将此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 个答案:

答案 0 :(得分:1)

我认为这是可行的,但绝不容易......

这应该有效:

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. 的模板元素
  3. 使用VisualStateManager.GetVisualStateGroups()静态方法获取当前的visualStateGroups
  4. 从集合中获取您想要的组或创建一个新组并将其添加到集合
  5. 在此论坛中添加新的visualState
  6. 希望这会有所帮助。

答案 1 :(得分: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);