0

I'm trying to write a simple (stand alone) C# extension method to do a Fade-In of a generic WPF UIElement, but the solutions (and code samples) that I found all contain a large number of moving parts (like setting up a story, etc...)

For reference here is an example of the type of API method I would like to create. This code will rotate an UIElement according to the values provided (fromValue, toValue, duration and loop)

public static T rotate<T>(this T uiElement, double fromValue, double toValue, int durationInSeconds, bool loopAnimation)
    where T : UIElement
{
    return (T)uiElement.wpfInvoke(
            ()=>{
                    DoubleAnimation doubleAnimation = new DoubleAnimation(fromValue, toValue, new Duration(TimeSpan.FromSeconds(durationInSeconds)));
                    RotateTransform rotateTransform = new RotateTransform(); 
                    uiElement.RenderTransform = rotateTransform;
                    uiElement.RenderTransformOrigin = new System.Windows.Point(0.5, 0.5);  
                    if (loopAnimation)
                        doubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
                    rotateTransform.BeginAnimation(RotateTransform.AngleProperty, doubleAnimation);
                    return uiElement;
                });
}
Dinis Cruz
  • 4,161
  • 2
  • 31
  • 49

2 Answers2

3

Sounds like you're looking for something like this:

public static T FadeIn<T>(this T uiElement, int durationInSeconds)
{
  return uiElement.FadeFromTo(0, 1, durationInSeconds, false);
}
public static T FadeOut<T>(this T uiElement, int durationInSeconds)
{
  return uiElement.FadeFromTo(1, 0, durationInSeconds, false);
}

public static T FadeFromTo<T>(this T uiElement,
                              double fromOpacity, double toOpacity,
                              int durationInSeconds, bool loopAnimation)
where T : UIElement
{
  return (T)uiElement.wpfInvoke(()=>
  {
    var doubleAnimation =
      new DoubleAnimation(fromOpacity, toOpacity,
                          new Duration(TimeSpan.FromSeconds(durationInSeconds)));
    if(loopAnimation)
      doubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
    uiElement.BeginAnimation(UIElement.OpacityProperty, doubleAnimation);
    return uiElement;
   });
}
Ray Burns
  • 62,163
  • 12
  • 140
  • 141
  • Sweet, thanks I knew that there should be an easier way :) I works ok, except when I try to run one after the other (but I think that that might be some threading issue) – Dinis Cruz Jun 16 '10 at 16:33
  • It is not a threading issue. Perhaps you are looking for Compose behavior. If so, pass `HandoffBehavior.Compose` as a third argument to BeginAnimation. On the other hand, perhaps you want to animate from the current value, in which case you should leave the default HandoffBehavior alone (it defaults to `SnapshotAndReplace`) but pass in null for "fromOpacity" in FadeIn and FadeOut. Note: To accept nulls, FadeFromTo needs to take arguments of type `double?` and construct the DoubleAnimation thusly: `new DoubleAnimation { From = fromOpacity, To=toOpacity, Duration = ... };` – Ray Burns Jun 16 '10 at 16:55
1

Here is the solution for the Grid.

Where the Grid is **<Grid Name="RootGrid" Opacity="0">**

 this.Dispatcher.Invoke(DispatcherPriority.Background, new Action(() =>
            {
                var doubleAnimation = new DoubleAnimation(0, 1, new Duration(TimeSpan.FromSeconds(5)));
                RootGrid.BeginAnimation(UIElement.OpacityProperty, doubleAnimation);
            }));
NoWar
  • 36,338
  • 80
  • 323
  • 498