2009-03-30 3 views
35

Я пытаюсь пометить новый элемент управления в области приложения, который программно добавляется после удаления существующих элементов управления. Мой код выглядит следующим образом:Использование анимации раскадровки на программно добавленном элементе управления

 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“.»

Что я могу сделать неправильно? Я довольно уверен, что я зарегистрировал все правильно :(

ответ

57

Я бы не стычка с 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(); 
+1

У меня возникли проблемы с этим ответом, потому что мы нацелены на .NET 3.0; даже если SetTarget был добавлен в .NET 3.0 SP2, это доступно только с установщиком .NET 3.5; поэтому, если вы хотите поддерживать .NET 3.0 SP1, мне нужно было использовать решение Carlos для перехода на «sb.Begin (this)». –

+1

[Вот вопрос] (http://stackoverflow.com/questions/13217221/settarget-vs-registername-settargetname), который иллюстрирует случай, когда 'SetTarget' не работает, а комманда' RegisterName'/'SetTargetName' необходимо. – dharmatech

+1

Отличная работа ... Хорошо –

5

Я согласен, что, вероятно, namescopes неправильная вещь для использования в этом сценарии. Намного проще и проще использовать 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); 
11

Я решил проблему, используя это в качестве параметра в методе начать, попробуйте:

sb.Begin(this); 

Поскольку имя регистрируется в окне.

+0

спасибо, этот очень полезный отзыв также решил мою проблему. – Tobias

+0

+1 Он решил именно эту проблему, без необходимости кодировать ничего нового. – Sonhja

+0

Поскольку моя панель рассказа была определена в ресурсах app.xaml, мне нужно было добавить параметр в SB.Begin (App.Current.MainWindow); – Chandru

0

Можно странно, но мое решение использовать оба метода:

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; 
      } 
     } 
Смежные вопросы