简体   繁体   English

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

[英]How to add new Visual States to a Custom control template dynamically in code?

Is it possible to add a new VisualState to a CustomControl Template 's VisualStateManager programmatically in code? 是否可以以编程方式在代码中向CustomControl TemplateVisualStateManager添加新的VisualState
For example, I can add to a CustomControl Template this XAML manually in design-time: 例如,我可以在设计时将XAML手动添加到CustomControl模板中:

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

But how could I add a new VisualState in runtime? 但是,如何在运行时添加新的VisualState

You should create the Group itself using XAML I suggest, then you have to find the VisualStateGroup you are Looking for like this: 我建议您使用XAML创建Group本身,然后必须找到要查找的VisualStateGroup,如下所示:

VisualStateGroup visualStateGroupLookingFor = null;
var visualStateGroups = (VisualStateManager.GetVisualStateGroups(LayoutRoot));
foreach (VisualStateGroup state in visualStateGroups) {
    if (state.Name == "VisualStateGroupMine") {
        visualStateGroupLookingFor = state;
        break;
        }
    }

Then, you have to create a new VisualState and Storyboard to add, for example: 然后,您必须创建一个新的VisualState和Storyboard进行添加,例如:

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

Now, create the animation: 现在,创建动画:

var animation = new DoubleAnimation();
animation.To = 10.0;

And set the target of the animation: 并设置动画的目标:

//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));

Finally add the animation(s) to your storyboard, give it a name, add it to the visualstategroup: 最后,将动画添加到情节提要中,为其命名,然后将其添加到visualstategroup中:

storyBoard.Children.Add(animation);
visualState.Storyboard = storyBoard;
visualState.Name = "CoolNameLikeWidthAnimation";
visualStateGroupLookingFor.States.Add(visualState);

Thats it, trigger it as usual with 就是这样,像往常一样触发它

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

I think this is doable, but by no means easy... 我认为这是可行的,但绝非易事...

this should work: 这应该工作:

Grid grid = this.Template.FindName("RootElement", this) as Grid;
(VisualStateManager.GetVisualStateGroups(grid)).Add(new VisualStateGroup() { /* the code for your visualstategroup here */ });

(you'll need to adapt depending on the type of your template's root element's name, and the place where you set-up the visualstatemanager, but all in all this can work. (您需要根据模板的根元素名称的类型以及设置visualstatemanager的位置进行调整,但是所有这些都可以使用。

also, this adds a new visualStateGroup, not just a visualState. 此外,这还会添加一个新的visualStateGroup,而不仅仅是visualState。 If you want to add a VisualState to an existing visualStateGroup, you'll have to get the group from the collection first, but this is common "get element from a collection" stuff 如果要将VisualState添加到现有的visualStateGroup,则必须首先从集合中获取组,但这是常见的“从集合中获取元素”的东西

basically: 基本上:

  1. Get the template's element containing the visualStateManager 获取包含visualStateManager的模板的元素
  2. use the VisualStateManager.GetVisualStateGroups() static method to get the current visualStateGroups 使用VisualStateManager.GetVisualStateGroups()静态方法获取当前visualStateGroups
  3. get the group you want from the collection or create a new one and add it to the collection 从集合中获取所需的组,或创建一个新的组并将其添加到集合中
  4. add a new visualState in this group 在该组中添加一个新的visualState

hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM