views:

1518

answers:

3

I'm starting to kick Silverlight around (although it currently feels the other way around) by rewritting an existing ASP.NET application - as good a place to start as any I thought.

I have 'mastered' pulling data from a database, through a service and into a datagrid and also populating image elements in the rows. So far so good.

Now i'm stuck and have a headache!

I want to add a simple animation (a green rectangle moving over a red rectangle to display a % progress) to the last column of each row, but can't get it wired up.

My xaml looks like this:

<data:DataGrid.Columns>
.
.
.
.
<data:DataGridTemplateColumn>
    <data:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <StackPanel x:Name="AnimationPanel">
                <StackPanel.Resources>
                    <Storyboard x:Key="ShowProgress">
                        <DoubleAnimation Storyboard.TargetProperty="Width"
                                        Storyboard.TargetName="goalProgressBar_Complete"
                                         From="0" To="50"
                                        Duration="0:0:5">
                        </DoubleAnimation>
                    </Storyboard>
                </StackPanel.Resources>
                <Rectangle x:Name="goalProgressBar_Complete"
                           Width="1" Height="100"
                           Fill="#0aa60e"></Rectangle>
            </StackPanel>
        </DataTemplate>
    </data:DataGridTemplateColumn.CellTemplate>
</data:DataGridTemplateColumn>
</data:DataGrid.Columns>

which is quite obviously wrong (because it doesn't work) and I am starting to think that it just is not possible to add animation to a Datagrid in this way. I've Googled hard looking for a piece of code and while there have been some tantilising results they have not amounted to anything.

Am I trying to do something that Silverlight simply does not support or am I missing something really straightforward?

Thanks in advance.

Edit: Full xaml @ http://daves.stackoverflow.s3.amazonaws.com/stackoverflow.txt

Update: Although I'm not out of the woods yet I have managed to get the animation running with the appropriate column. The answer provided by MasterMax led me to look at EventTriggers and the revised xaml looks like this:

<data:DataGridTemplateColumn>
    <data:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Rectangle x:Name="GoalProgress" Height="100" Width="1" Fill="Green">
                <Rectangle.Triggers>
                    <EventTrigger RoutedEvent="Rectangle.Loaded">
                        <EventTrigger.Actions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetProperty="Width"
                                             Storyboard.TargetName="GoalProgress"
                                             From="0" To="50" Duration="0:0:5">
                                    </DoubleAnimation>
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger.Actions>
                    </EventTrigger>
                </Rectangle.Triggers>
            </Rectangle>
        </DataTemplate>
    </data:DataGridTemplateColumn.CellTemplate>
</data:DataGridTemplateColumn>

All I need to do now is bind in the % value in the 'To' property and add my underlying Red rectangle. No doubt this will not prove as easy as I'm currently hoping but then it wouldn't be fun otherwise would it ;-)

A: 

for that type of application, an animation may not be the best solution. you may want to try binding the width property of the moving rectangle to a variable in your application, or adjust the width with each tick as the progress changes.

MasterMax1313
In the original application there was a dynamically generated image in the column. I can do this again but wanted to show some 'value add' with Silverlight.
DilbertDave
Just to clarify, the progress related to a Goal/Project which will be completed over many days/weeks/months - not while viewing the page so the animation only needs to run with the control is loaded - just to add some pizazz
DilbertDave
I see. As you guessed, I thought you were aiming for a normal progress bar, not something that behaves more like a graph. I'll think a bit more about it (I see your comments to Jeff below).
MasterMax1313
+1  A: 

It looks to me like you aren't actually playing the storyboard. You need to add mouse enter and mouse leave handlers for your rectangle and then play and stop your storyboard accordingly. Make sure to both stop and then play the storyboard in the enter command (otherwise you get some interesting side-effects).

Update

Okay, having spent my day neck deep in Silverlight, I'm not much closer to helping. I was looking at the generic.xaml file inside the Silverlight assembly containing the DataGrid. You might consider taking a look in there. From what I can see, they achieve some of this for the row details transition with control templating though I haven't looked at the corresponding code yet to determine exactly how.

Jeff Yates
Ah - that's the problem! In code I can't access the ShowProgress.Begin() method. If I move the StackPanel outside of the datagrid then I can (but it's in the wrong place)
DilbertDave
You can retrieve the storyboard from the stack panel's resources.
Jeff Yates
You just reference it like ((Storyboard)AnimationPanel.Resources["ShowProgress"])
Jeff Yates
No Luck - AnimationPanel not in scope either.
DilbertDave
Hmm, I think we need to see more of your source. The stack panel will be in scope for whatever xaml page contains the DataGrid.
Jeff Yates
Full xaml @ http://daves.stackoverflow.s3.amazonaws.com/stackoverflow.txt
DilbertDave
Thanks for your efforts Jeff - I hope it didn't take you off something more fruitful ;-)
DilbertDave
You're welcome. Some of it was actually inline with what I was trying to do on my own project so I didn't take too much time out. It was interesting to look into, I just wish I'd had more time to actually attempt coding a solution. Still might, now you've got the hard part done. ;o)
Jeff Yates
+1  A: 

Try attaching it to the EventTrigger for the Datagrid. Something similar to this:

<Window.Triggers>
        <EventTrigger RoutedEvent="Window.Loaded">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation Name="EntranceAnimation"
                        Storyboard.TargetName="MainWindow" 
                        Storyboard.TargetProperty="Opacity"
                        From="0.0"
                        To="1.0"
                        Duration="0:0:3">
                    </DoubleAnimation>
                </Storyboard>
                </BeginStoryboard>
        </EventTrigger>
    </Window.Triggers>

In your case you'd be looking for the DataGrid.Loaded event (or something similar). This works for me, and I'm fading the whole window in on page loaded.

MasterMax1313