0

I need to place numerous Image controls on an InkCanvas. All of them need to animate when certain code conditions are met. After numerous attempts my ControlTemplate is still not right.

<ControlTemplate x:Key="AnimatedImage" TargetType="{x:Type Image}">
    <Grid>
        <Image Name="image" 
               Source="{TemplateBinding Filename}"
               Width="{TemplateBinding Width}"
               Height="{TemplateBinding Height}"
               HorizontalAlignment="Center"
               VerticalAlignment="Center">

            <VisualStateManager.VisualStateGroups>
                <VisualStateGroup Name="AnimationLocations">

                    <!-- When the image is first loaded move it to the center of the InkCanvas -->
                    <VisualState Name="AnimateToCenterScreen">
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetName="image"
                                             Storyboard.TargetProperty="(Image.RenderTransform).(TranslateTransform.X)"
                                             From="{TemplateBinding From}"
                                             To="{TemplateBinding To}"
                                             Duration="{TemplateBinding Duration}" />
                        </Storyboard>
                    </VisualState>

                    <!-- Animate the image to an off screen position to effectively hide it.  -->
                    <VisualState Name="AnimateToOffScreen">
                        <!-- To be filled in later.  -->
                    </VisualState>

                    <!-- Animate the image back to the original on screen position.  -->
                    <VisualState Name="AnimateToOnScreen">
                        <!-- To be filled in later.  -->
                    </VisualState>
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
        </Image>
    </Grid>
</ControlTemplate>

Here is the xaml for the main grid:

        <Image Name="image1" 
               Template="{StaticResource AnimatedImage}"
               Source="{Binding Path=Image1}" 
               Visibility="{Binding ElementName=chkShowPerson, Path=IsChecked, Converter={StaticResource b2v}}" 
               HorizontalAlignment="Center" 
               VerticalAlignment="Center" >
        </Image>
    </InkCanvas>
</Grid>

1 Answers1

0

The VisualStateManager element has to be located as the child of the control template's root.

<ControlTemplate x:Key="AnimatedImage" TargetType="{x:Type Image}">
    <Grid>
        <VisualStateManager.VisualStateGroups>
            ...
        </VisualStateManager.VisualStateGroups>

        <Image Name="image" ... />
    </Grid>
</ControlTemplate>

(For reference here is the page on MSDN where you can find that tidbit.)

McGarnagle
  • 101,349
  • 31
  • 229
  • 260
  • Thank you for responding so quickly. – user2986938 Sep 04 '14 at 16:32
  • Thank you for responding so quickly. Even after making your suggested changes, I still can't use the AnimatedImage as a template on an Image control. The Image control doesn't have a Template property. If it is not too much trouble, may I ask for an example of a controltemplate with an xtype of Image and how to refer to that template on an image control? – user2986938 Sep 04 '14 at 16:38
  • @user2986938 ah sorry, I didn't notice you were trying to use TemplateBinding on the animation properties. The properties `To`, `From`, and `Duration` are not dependency properties, so you can not bind them. You'll need to find some other way. – McGarnagle Sep 04 '14 at 17:19
  • @user2986938 you might want to take a look at `FluidMoveBehavior` -- if you can make use of that, it could simplify your task. http://msdn.microsoft.com/en-us/library/dn195722.aspx – McGarnagle Sep 04 '14 at 17:19
  • If I understand this correctly (which I probably don't) I can create my own dependency properties. So that is not the bottleneck that I am experiencing. My question has more to do with the Template property on the Image control. Is it even possible to create a ControlTemplate for an Image and then use it for an Image? If so how? Or better yet, what is the best way to get this done?...UserControl, CustomControl, duplication of code? Again thank you very much for your time and expertise. – user2986938 Sep 04 '14 at 19:03
  • @user2986938 oh ... sorry again, I missed that too. No, you can't create a `ControlTemplate` for an Image, because it doesn't derive from `Control`. You could wrap the Image in a ContentControl or similar, but it does not seem from your example that that would gain you anything. Looks like it would be best to use plain `Image` controls, and animate their `InkCanvas.Left` / `InkCanvas.Top` properties. – McGarnagle Sep 04 '14 at 19:19