views:

39

answers:

1

I am not looking to create new events. I need to create a canvas control that optionally fades in or out depending on whether or not the mouse is over it. The code below probably explains what I want to do better than I can.

        private Storyboard fadeInStoryboard;
    private Storyboard fadeOutStoryboard;
    public FadingOptionPanel()
    {
        InitializeComponent();
    }
    public static readonly DependencyProperty FadeEnabledProperty =
    DependencyProperty.Register("IsFadeEnabled", typeof(bool), typeof(FadingOptionPanel), new FrameworkPropertyMetadata(true,
                   OnFadeEnabledPropertyChanged,
                   OnCoerceFadeEnabledProperty));
    public bool IsFadeEnabled
    {
        get
        {
            return (bool)GetValue(FadeEnabledProperty);
        }
        set
        {
            SetValue(FadeEnabledProperty, value);
        }
    }
    private static void OnFadeEnabledPropertyChanged(DependencyObject source,
    DependencyPropertyChangedEventArgs e)
    {

    }
    private static object OnCoerceFadeEnabledProperty(DependencyObject sender, object data)
    {
        if (data.GetType() != typeof(bool))
        {
            data = true;
        }
        return data;
    }

    private void FadingOptionPanel_MouseEnter(object sender, MouseEventArgs e)
    {
        if (IsFadeEnabled)
        {
            fadeInStoryboard.Begin(this);
        }
    }
    private void FadingOptionPanel_MouseLeave(object sender, MouseEventArgs e)
    {
        if (IsFadeEnabled)
        {
            fadeOutStoryboard.Begin(this);
        }
    }
    private void FadingOptionsPanel_Loaded(object sender, RoutedEventArgs e)
    {
        //Initialize Fade In Animation
        DoubleAnimation fadeInDoubleAnimation = new DoubleAnimation();
        fadeInDoubleAnimation.From = 0;
        fadeInDoubleAnimation.To = 1;
        fadeInDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(.5));
        fadeInStoryboard = new Storyboard();
        fadeInStoryboard.Children.Add(fadeInDoubleAnimation);
        Storyboard.SetTargetName(fadeInDoubleAnimation, this.Name);
        Storyboard.SetTargetProperty(fadeInDoubleAnimation, new PropertyPath(Canvas.OpacityProperty));

        //Initialize Fade Out Animation
        DoubleAnimation fadeOutDoubleAnimation = new DoubleAnimation();
        fadeOutDoubleAnimation.From = 1;
        fadeOutDoubleAnimation.To = 0;
        fadeOutDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(.2));
        fadeOutStoryboard = new Storyboard();
        fadeOutStoryboard.Children.Add(fadeOutDoubleAnimation);
        Storyboard.SetTargetName(fadeOutDoubleAnimation, this.Name);
        Storyboard.SetTargetProperty(fadeOutDoubleAnimation, new PropertyPath(Canvas.OpacityProperty));
    }

I originally was using this code inside a usercontrol instead of a custom control before I found out that usercontrols don't support content.

+1  A: 

One way is to override the corresponding OnXxx methods. For example:

protected override void OnMouseEnter(MouseEventArgs e)
{
  base.OnMouseEnter(e);
  if (IsFadeEnabled)
  {
    fadeInStoryboard.Begin(this);
  }
}

You can also add an event subscription in your constructor:

public FadingOptionPanel()
{
  this.MouseEnter += FadingOptionPanel_MouseEnter;
}

Note that for running a storyboard on an event, you can often do this without code-behind by using EventTriggers -- but I'm not sure offhand whether an EventTrigger-based approach could be made to respect your IsFadeEnabled property.

itowlson
Thanks. However I'm getting an error "'' name cannot be found in the name scope of 'Minimalistic_Writer.FadingCanvas'." at "fadeInStoryboard.Begin(this);"
Justin
My guess is that, in your Loaded handler, this.Name is returning null. Try setting the Target property rather than TargetName, e.g. `Storyboard.Target = this;`.
itowlson
Thank you very much!
Justin