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

发布于 2024-10-20 23:22:39 字数 552 浏览 2 评论 0原文

是否可以在代码中以编程方式将新的 VisualState 添加到 CustomControl TemplateVisualStateManager 中?
例如,我可以在设计时手动将此 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 呢?

Is it possible to add a new VisualState to a CustomControl Template's VisualStateManager programmatically in code?
For example, I can add to a CustomControl Template this XAML manually in design-time:

<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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

猫九 2024-10-27 23:22:39

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

这应该可行:(

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. 在该组中添加一个新的视觉状态

希望这有帮助。

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.

also, this adds a new visualStateGroup, not just a 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

basically:

  1. Get the template's element containing the visualStateManager
  2. use the VisualStateManager.GetVisualStateGroups() static method to get the current 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

hope this helps.

聽兲甴掵 2024-10-27 23:22:39

我建议您应该使用 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));

最后添加动画)到你的故事板,给它一个名字,将它添加到视觉状态组:

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

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

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

You should create the Group itself using XAML I suggest, then
you have to find the VisualStateGroup you are Looking for like this:

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:

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:

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文