【问题标题】:Using a Storyboard animation on a programmatically-added control在以编程方式添加的控件上使用情节提要动画
【发布时间】:2010-10-16 07:08:16
【问题描述】:

我正在尝试将新控件淡入到我的应用程序的“应用程序”区域,该区域是在删除现有控件后以编程方式添加的。我的代码如下所示:

        void settingsButton_Clicked(object sender, EventArgs e)
    {
        ContentCanvas.Children.Clear();

        // Fade in settings panel
        NameScope.SetNameScope(this, new NameScope());

        SettingsPane s = new SettingsPane();
        s.Name = "settingsPane";

        this.RegisterName(s.Name, s);
        this.Resources.Add(s.Name, s);

        Storyboard sb = new Storyboard();

        DoubleAnimation settingsFade = new DoubleAnimation();
        settingsFade.From = 0;
        settingsFade.To = 1;
        settingsFade.Duration = new Duration(TimeSpan.FromSeconds(0.33));
        settingsFade.RepeatBehavior = new RepeatBehavior(1);
        Storyboard.SetTargetName(settingsFade, s.Name);
        Storyboard.SetTargetProperty(settingsFade, new PropertyPath(UserControl.OpacityProperty));

        ContentCanvas.Children.Add(s);

        sb.Children.Add(settingsFade);
        sb.Begin();
    }

但是,当我运行此代码时,我收到错误“没有适用的名称范围来解析名称 'settingsPane'。”

我可能做错了什么?我很确定我已经正确注册了所有内容:(

【问题讨论】:

    标签: wpf animation storyboard


    【解决方案1】:

    我不会为 NameScopes 等而烦恼,而是宁愿使用 Storyboard.SetTarget。

    var b = new Button() { Content = "abcd" };
    stack.Children.Add(b);
    
    var fade = new DoubleAnimation()
    {
        From = 0,
        To = 1,
        Duration = TimeSpan.FromSeconds(5),
    };
    
    Storyboard.SetTarget(fade, b);
    Storyboard.SetTargetProperty(fade, new PropertyPath(Button.OpacityProperty));
    
    var sb = new Storyboard();
    sb.Children.Add(fade);
    
    sb.Begin();
    

    【讨论】:

    • 我在回答这个问题时遇到了麻烦,因为我们的目标是 .NET 3.0;即使 SetTarget 已添加到 .NET 3.0 SP2,这也仅适用于 .NET 3.5 安装程序;所以如果你想支持 .NET 3.0 SP1,我需要使用 Carlos 的解决方案来更改为“sb.Begin(this)”。
    • Here's a question 这说明了SetTarget 不起作用并且RegisterName/SetTargetName 组合是必要的情况。
    【解决方案2】:

    我在begin方法中使用这个作为参数解决了这个问题,试试:

    sb.Begin(this);
    

    因为名字是在窗口中注册的。

    【讨论】:

    • +1 它完全解决了问题,无需编写任何新代码。
    • 因为我的故事板是在 app.xaml 资源中定义的,所以我需要将参数添加为 SB.Begin(App.Current.MainWindow);
    • 在我的情况下,我需要为其提供 InnerControl: FrameworkElement innerControl = this.Descendents(1).First() as FrameworkElement;故事板 IndeterminateStoryboard = VisualStateManager.GetVisualStateGroups(innerControl).OfType().Single(x => x.Name == "CommonStates").States.OfType().Single(x => x.Name = =“不确定”)。故事板; IndeterminateStoryboard.Begin(innerControl);
    【解决方案3】:

    我同意,在这种情况下使用名称范围可能是错误的。使用 SetTarget 比使用 SetTargetName 更简单、更容易。

    如果它对其他人有帮助,这里是我用来突出显示表格中特定单元格的方法,其中突出显示会衰减为空。添加新答案时,它有点像 StackOverflow 的突出显示。

        TableCell cell = table.RowGroups[0].Rows[row].Cells[col];
    
        // The cell contains just one paragraph; it is the first block
        Paragraph p = (Paragraph)cell.Blocks.FirstBlock;
    
        // Animate the paragraph: fade the background from Yellow to White,
        // once, through a span of 6 seconds.
    
        SolidColorBrush brush = new SolidColorBrush(Colors.Yellow);
        p.Background = brush;
        ColorAnimation ca1 = new ColorAnimation()
        {
                From = Colors.Yellow,
                To = Colors.White,
                Duration = new Duration(TimeSpan.FromSeconds(6.0)),
                RepeatBehavior = new RepeatBehavior(1),
                AutoReverse = false,
        };
    
        brush.BeginAnimation(SolidColorBrush.ColorProperty, ca1);
    

    【讨论】:

      【解决方案4】:

      这可能很奇怪,但我的解决方案是同时使用这两种方法:

      Storyboard.SetTargetName(DA, myObjectName);
      
      Storyboard.SetTarget(DA, myRect);
      
      sb.Begin(this);
      

      在这种情况下没有错误。

      看看我用过的代码。

       int n = 0;
              bool isWorking;
              Storyboard sb;
              string myObjectName;
               UIElement myElement;
      
              int idx = 0;
      
              void timer_Tick(object sender, EventArgs e)
              {
                  if (isWorking == false)
                  {
                      isWorking = true;
                      try
                      {
                            myElement = stackObj.Children[idx];
      
                          var possibleIDX = idx + 1;
                          if (possibleIDX == stackObj.Children.Count)
                              idx = 0;
                          else
                              idx++;
      
                          var myRect = (Rectangle)myElement;
      
                         // Debug.WriteLine("TICK: " + myRect.Name);
      
                          var dur = TimeSpan.FromMilliseconds(2000);
      
                          var f = CreateVisibility(dur, myElement, false);
      
                          sb.Children.Add(f);
      
                          Duration d = TimeSpan.FromSeconds(2);
                          DoubleAnimation DA = new DoubleAnimation() { From = 1, To = 0, Duration = d };
      
                          sb.Children.Add(DA);
                          myObjectName = myRect.Name;  
                         Storyboard.SetTargetName(DA, myObjectName);
                         Storyboard.SetTarget(DA, myRect);
      
                          Storyboard.SetTargetProperty(DA, new PropertyPath("Opacity"));
      
                          sb.Begin(this);
      
                          n++;
                      }
                      catch (Exception ex)
                      {
                          Debug.WriteLine(ex.Message + "   " + DateTime.Now.TimeOfDay);
                      }
      
                      isWorking = false;
                  }
              }
      

      【讨论】:

        猜你喜欢
        • 2012-05-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-20
        • 2010-12-28
        • 2016-07-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多