Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I bind a xaml storyboard to a custom control's Point property in WP7?

I am trying to cause a Grid (and all the controls on it) to shake in my WP7 app. Seems the best way to offset the grid is using the Margin property, but there is no ThicknessAnimationUsingKeyFrames supported in WP7 so I can't do it directly.

Instead, I have created a custom control:

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;

namespace MyNamespace
{
  // Grid which has an OriginOffset property that is tied to the margin,
  // and thus can be animated.

  public class OffsettableGrid : Grid
  {
    public OffsettableGrid()
    {
    }

    public static readonly DependencyProperty OriginOffsetProperty = 
        DependencyProperty.Register(
        "OriginOffset", typeof(Point), typeof(OffsettableGrid), null);

    public Point OriginOffset
    {
      get
      {
        return new Point(Margin.Left, Margin.Top);
      }
      set
      {
        Margin = new Thickness(value.X, value.Y,
          Margin.Right, Margin.Bottom);
      }
    }
  }
}

and then in xaml I declare a storyboard as follows:

<Storyboard x:Name="m_shakeStoryboard" 
            RepeatBehavior="5x" 
            AutoReverse="False" 
            SpeedRatio="5">

    <PointAnimationUsingKeyFrames 
        BeginTime="00:00:00"
        Storyboard.TargetName="m_chooseAnswerGrid"
        Storyboard.TargetProperty="(OffsettableGrid.OriginOffset)">

        <EasingPointKeyFrame KeyTime="00:00:00"    Value="0,0"/>
        <EasingPointKeyFrame KeyTime="00:00:00.2"  Value="-10,0"/>
        <EasingPointKeyFrame KeyTime="00:00:00.4"  Value="10,0"/>
        <EasingPointKeyFrame KeyTime="00:00:00.6"  Value="0,0"/>
    </PointAnimationUsingKeyFrames>

</Storyboard>

and then of course I declare my grid using .

But when I go to start the storyboard:

m_shakeStoryboard.Begin();

my OriginOffset property never gets invoked. I put a breakpoint at "Margin = new Thickness(value.X, value.Y," but it never gets hit. What am I doing wrong?

In the editor, whenever I change OriginOffset, the margins change as well as expected.

Any help much appreciated! Thanks

like image 910
swinefeaster Avatar asked Dec 12 '25 15:12

swinefeaster


2 Answers

You might want to check this out. Aren't you going to have to use an EventTrigger or something to start the StoryBoard? And I don't think you need the parenthesis's, Storyboard.TargetProperty="(OffsettableGrid.OriginOffset)"

          <EventTrigger RoutedEvent="Button.Click">    
            <BeginStoryboard>
              <Storyboard>
                <ColorAnimation 
                  Storyboard.TargetName="myAnimatedBrush"
                  Storyboard.TargetProperty="Color"
                  From="Red" To="Blue" Duration="0:0:7" />
              </Storyboard>
            </BeginStoryboard>
          </EventTrigger>
like image 68
Derek Beattie Avatar answered Dec 14 '25 05:12

Derek Beattie


Your dependency property is not well defined. You should use SetValue and GetValue:

public Point OriginOffset
{
   get
   {
       return (Point)GetValue(OriginOffsetProperty);
   }
   set
   {
       SetValue(OriginOffsetProperty, value);
   }
}

Then add a callback to the PropertyMetadata of the dependency property, to set the margin:

public static readonly DependencyProperty OriginOffsetProperty = 
    DependencyProperty.Register(
        "OriginOffset", 
        typeof(Point), 
        typeof(OffsettableGrid), 
        new PropertyMetadata(new PropertyChangedCallback(OnOriginOffsetChanged)));
like image 37
alf Avatar answered Dec 14 '25 06:12

alf