Skip to main content
Home Forums General Silverlight New Features in Silverlight 3 Why does this storyboard work in a page, but not in app.xaml?
10 replies. Latest Post by mtiede@swtechnologies.com on July 7, 2009.
(0)
mtiede@s...
Member
148 points
275 Posts
07-04-2009 9:28 AM |
<navigation:Page.Resources> <Storyboard x:Name="FadeIn"> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(UIElement.Opacity)"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/> <SplineDoubleKeyFrame KeyTime="00:00:01" Value="1"/> </DoubleAnimationUsingKeyFrames> </Storyboard>...
When I put this in app.xaml's resources and try to Begin it, I get a message saying "cannot find targetname LayoutRoot". The page definitely has a LayoutRoot. Is it somehow looking for app to have a layoutroot?
jay nana...
Contributor
3388 points
624 Posts
07-04-2009 9:39 AM |
LayoutRoot is defined in Page.xaml and not in App.xaml. So try to set TargetName dynamically in code behind like this:
FadeIn.SetValue(Storyboard.TargetNameProperty, LayoutRoot.Name)
FadeIn.Begin();
07-05-2009 6:24 AM |
That didn't work. And I don't think it is actually doing anything differently. I think you are correct that the resource is looking at its container's elements for that targetnameproperty. And all the code has done is change when the literal is looked up, but hasn't changed WHERE it is looking for that name (app.xaml).
Other ideas?
07-05-2009 6:49 AM |
07-05-2009 6:51 AM |
well, you should take out "Storyboard.TargetName="LayoutRoot" line from fadeIn storyboard.And it is perfectly working with me. I have build some animations in app.xaml and I use them for different control by just specifying targetname dynamically.
07-05-2009 7:06 AM |
hey got your problem after looking at my code:
you need to do like this:
Storyboard sb = Application.Current.Resources["fadeIn"] as Storyboard; DoubleAnimationUsingKeyFrames d1 = sb.Children[0] as DoubleAnimationUsingKeyFrames ; Storyboard.SetTarget(d1, LayoutRoot); sb.Begin();
07-05-2009 8:01 AM |
Ah, that looks more like it. And it makes sense (though I would have NEVER thought of it). I'll give it a whack and see how it works.
07-05-2009 9:25 AM |
Now that I have that part working, I'm on to the next part of this problem that I don't understand.
I am using the navigation framework and my main page has a Frame that is being navigated. I wanted all the pages navigated to to have this fading action. I thought I could use the resources in the app.xaml and just make a resource and a merged resource dictionary. I couldn't get this to work. Probably did something wrong syntactically somewhere.
So now I'm thinking to just have the main page fade the pages that it is navigating. So I did this on the Navigated event:
method MainPage.MainFrame_Navigated( sender: System.Object; e: System.Windows.Navigation.NavigationEventArgs ); var d1 : DoubleAnimationUsingKeyFrames; FadeRoot : UIElement; begin FadeIn.Stop; FadeRoot := MainFrame.FindName( 'LayoutRoot' ) as UIElement; Storyboard.SetTarget( FadeIn, FadeRoot ); try d1 := FadeIn.Children[0] as DoubleAnimationUsingKeyFrames ; StoryBoard.SetTarget( FadeIn, FadeRoot ); FadeIn.Begin; except on Em : Exception do begin MessageBox.Show( Em.Message ); end; end; end;
It fades all right. Only problem is it is the WHOLE browser page content that fades. I thought the MainFrame.FindName would look for elements below itself, but it keeps finding the main page's theme tag (which is the very outer container element on the main page).
So how do I find the page object that was just navigated to so that I can get its "LayoutRoot"?
07-05-2009 2:44 PM |
What about having fadeIn called in each page's Loaded event?
So whenever the page loads, its fades in the view. In this case, you can your app.xaml one fadeIn animation and call it from Loaded event of the UserControl.
07-05-2009 4:29 PM |
I've been trying to figure out a way so that the code only has to go ONE place. As opposed to putting it in every page. What I'm trying now is to make a new base Page class and change the inheritance of the pages to that. Then I can have the base class do the fading in and I don't have to put that code in a lot of places. There is probably a .Net way of doing that that is better, but I'm not that familar with those yet.
...time passes...
I'm not getting anywhere try to make a Page inheritance scheme either. Trouble with using the wrong xaml or not knowing what InitializeComponent is.
I give up for today...
07-07-2009 11:13 AM |
I have it all working now. I created a FadeIn and FadeOut class that gets their animation from App.xaml. As pages are requested, the current page fades out, navigation happens to the next page, the new page fades in when loaded.
I solved the FindName namescope problem by using VisualTreeHelper with VisualTreeWalker found elsewhere.
I am doing all the fading in the MainPage around the click events. Here is the constructor that creates the faders:
constructor MainPage; begin InitializeComponent(); fVisualTreeWalker := new VisualTreeWalker; fadeOut := new FadeOut; fadeOut.Completed := @NavigateNextUri; fadeIn := new FadeIn; MainFrame.Navigated += MainFrame_Navigated; end;
Here is the code the FadeOut executes after it is finished:
method MainPage.NavigateNextUri( sender : Object; e : EventArgs ); begin MainFrame.Navigate( NextUri ); end;
Here is what happens on clicks:
method MainPage.About_Click(sender: System.Object; e: System.Windows.RoutedEventArgs); begin NavigateTo( '/Views/About.xaml' ); end;
And here how the navigation starts the fade out which will then trigger the actual navigation:
procedure MainPage.NavigateTo( UriString : String ); begin Cursor := Cursors.Wait; NextUri := new Uri( UriString, UriKind.Relative ); fadeOut.LayoutRoot := fVisualTreeWalker.FindName( 'LayoutRoot', MainFrame ); fadeOut.Fade; end;
And lastly, here is where the Page fades in the new page (which is defined with Opacity=0)
method MainPage.MainFrame_Navigated( sender: System.Object; e: System.Windows.Navigation.NavigationEventArgs ); begin fadeIn.LayoutRoot := fVisualTreeWalker.FindName( 'LayoutRoot', MainFrame ); fadeIn.Fade; Cursor := Cursors.Arrow; end;
Hope it helps someone else.
I suppose I should make the faders usercontrols and set up some dependency properties so all this code could maybe be removed, but I have a deadline :-)