在故事板上定义并在XAML中启动的GetCurrentState

Sli*_*ppy 5 wpf xaml storyboard

我到处搜索,似乎无法找到答案.我的应用程序生活在松散的XAML世界中,因此必须依靠XamlReaders和树木行走来寻找元素.我有一个处理这些XAML页面呈现的组件.该渲染器需要知道可以在加载的XAML上运行的故事板的状态.所以我想在渲染器中做的是这样的: -

var resources = _currentScreenFrameworkElement.Resources;
foreach (var item in resources.Values)
{
    if (item is Storyboard)
    {
        try
        {
            var storyboard = item as Storyboard;
            **if (storyboard.GetCurrentState() == ClockState.Active)**
Run Code Online (Sandbox Code Playgroud)

一切都很好.但问题是当我尝试dcheck时,它会抛出一个异常: -

"Cannot perform action because the specified Storyboard was not applied to this object for interactive control."
Run Code Online (Sandbox Code Playgroud)

环顾四周,我看到它是因为我需要让故事板可控.所以我的问题是如何在XAML中执行此操作?我没有在代码中启动故事板,因此无法将true传递给重载的BeginStoryboard.

Bil*_*ell 5

我刚遇到同样的问题所以我想我会分享我的发现.

当故事板未标记为可控时,您会收到该错误.调用Begin方法时,故事板被标记为可控制.

如果你是从代码中执行它,那么你只需使用具有此IsControllableboolean参数的重载(Begin重载列表).

如果你在Xaml中使用了BeginAnimation元素,那么你需要做两件事.

  1. 将一个指定Name给BeginAnimation元素.此属性的文档说明:"如果未指定BeginStoryboard的名称,则故事板在开始后不会受到交互式影响"
  2. 当您尝试在代码隐藏中与故事板进行交互时,必须将引用传递给您声明BeginStoryboard的对象.

这是一个显示第1步(命名为beginstoryboard)的示例

<Button Name="btn1" Content="bla">
  <Button.Triggers>
    <EventTrigger RoutedEvent="Button.Click">
      <BeginStoryboard 
             Name="bnt1_beginStoryboard" 
             Storyboard={StaticResource someSharedStoryboard}"/>
    </EventTrigger>
  </Button.Triggers>
</Button>
Run Code Online (Sandbox Code Playgroud)

这是第2步的示例.由于您已经命名了beginStoryboard,因此可以将其用作类中的局部变量..或者您可以直接引用实际的故事板.重点是你必须传入beginStoryboard的所有者(在这种情况下是按钮)

//The main point here is that we're passing in btn1
bnt1_beginStoryboard.Storyboard.Stop(btn1);
bnt1_beginStoryboard.Storyboard.SkipToFill(btn1);
bnt1_beginStoryboard.Storyboard.Resume(btn1);
Run Code Online (Sandbox Code Playgroud)

这是故事板上所有"动作"方法的列表,要求您传递拥有的框架元素: 在故事板启动后控制故事板