2009-03-30 13 views
35

Estoy tratando de desvanecerme en un nuevo control en el área de la "aplicación" de mi aplicación que se agrega programáticamente después de que se eliminen los controles existentes. Mi código es el siguiente:Usando una animación Storyboard en un control agregado mediante programación

 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(); 
    } 

Sin embargo, cuando ejecuta este código, se produce el error "No existe un ámbito de nombres aplicable para resolver el nombre 'settingsPane'."

¿Qué estoy haciendo mal? Estoy bastante seguro de que me he registrado todo correctamente :(

Respuesta

57

yo no molestar con los NameScopes etc., y preferiría utilizar Storyboard.SetTarget lugar.

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

Tuve problemas con esta respuesta porque estamos apuntando a .NET 3.0; aunque SetTarget se haya agregado a .NET 3.0 SP2, esto solo está disponible con el instalador de .NET 3.5; así que si quieres soportar .NET 3.0 SP1, necesitaba usar la solución de Carlos para cambiar a "sb.Begin (this)". –

+1

[Aquí hay una pregunta] (http://stackoverflow.com/questions/13217221/settarget-vs-registername-settargetname) que ilustra un caso donde 'SetTarget' no funciona y el combo' RegisterName'/'SetTargetName' es necesario. – dharmatech

+1

Buen trabajo ... Bueno –

5

Estoy de acuerdo, los namescopes son probablemente Lo que no debe usarse para este escenario es SetTarget mucho más simple y fácil de usar que SetTargetName.

En caso de que ayude a alguien más, esto es lo que solía resaltar una celda particular en una tabla con un resaltado que se desvanece a nada Es un poco como el resaltado de StackOverflow cuando agrega una nueva respuesta.

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

He resuelto el problema usando esto como parámetro en el método de empezar, intente:

sb.Begin(this); 

Debido a que el nombre está registrado en la ventana.

+0

gracias, este consejo muy útil también resolvió mi problema – Tobias

+0

+1 Se solucionó exactamente el problema sin tener que codificar nada nuevo. – Sonhja

+0

Como mi storyboard se definió en los recursos de app.xaml, necesitaba agregar el parámetro como SB.Begin (App.Current.MainWindow); – Chandru

0

Es posible Lo curioso pero mi solución es utilizar ambos métodos:

Storyboard.SetTargetName(DA, myObjectName); 

Storyboard.SetTarget(DA, myRect); 

sb.Begin(this); 

En este caso no hay ningún error.

Eche un vistazo al código donde lo he usado.

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; 
      } 
     } 
Cuestiones relacionadas