开发者

Manage screen transitions with behaviors in silverlight

My app root visual is a border panel which stays fixed the whole time. What do changes is the Child of the border panel : I have made several screens (UserControl) and want to switch between them when certain buttons within each screen are clicked.

I want the transitions between the screens to be visually appealing so that each screen will have two StoryBoards , one for slide in animation and one for slide out animation. ( To make it clearer , The slide in animation of screen1 ,for example, will move screen1's buttons and fields in a specific way into the view area until they reach their final position ).

My goal is to achieve these screen transitions with a Behavior , and apply them to screens with as less code as possible ( Best will be XAML only).

First, I defiend a new Interface which all my app screens will implement :

public interface IScreenWithTransitions
    {
        void beginOutTransition();

        void beginInTransition();

        event EventHandler outTransitionEnded;
    }

And then screen1 code behind will look like this:

public partial class Screen1 : UserControl, IScreenWithTransitions
    {
        public Screen1()
        {
            // Required to initialize variables
            InitializeComponent();
        }

        public void beginOutTransition()
        {
            AnimationOut.Completed += outTransitionEnded;
            AnimationOut.Begin();           
        }

        public void beginInTransition()
        {
            AnimationIn.Begin();            
        }

        public event EventHandler outTransitionEnded; 
    }

AnimationOut and AnimationIn are StoryBoards which I created with Blend for each screen.

Now, I want to write a Behavior to manage the transition. This Behavior will act on a Button. It will have two properties. One is OldScreenContainer which is of type Panel and represents the container of the screen we want to remove. Second is NewScreen which is of type IScreenWithTransitions and represents the new screen that we want to put inside the container.

public class SwitchScreensBehavior : Behavior<Button>
    {
        public static readonly DependencyProperty NewScreenProperty = DependencyProperty.Register("NewScreen", typeof(IScreenWithTransitions), typeof(ChangeButtonTextBehavior), null);
        public static readonly DependencyProperty OldScreenContainerProperty = DependencyProperty.Register("OldScreenContainer", typeof(Panel), typeof(ChangeButtonTextBehavior), null);

        public IScreenWithTransitions NewScreen
        {
            get { return (IScreenWithTransitions)GetValue(SwitchScreensBehavior.NewScreenProperty); }
            set { SetValue(SwitchScreensBehavior.NewScreenProperty, value); }
        }

        public Panel OldScreenContainer
        {
            get { return (Panel)GetValue(SwitchScreensBehavior.OldScreenContainerProperty); }
            set { SetValue(SwitchScreensBehavior.OldScreenContainerProperty, value); }
        }

        protected override void OnAttached()
        {
            base.OnAttached();
            this.AssociatedObject.Click += AssociatedObject_Click;
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();
  开发者_高级运维          this.AssociatedObject.MouseLeftButtonUp -= AssociatedObject_Click;
        }

        void AssociatedObject_Click(object sender, RoutedEventArgs e)
        {

            IScreenWithTransitions oldPage = (IScreenWithTransitions)OldScreenContainer.Children[0];
            oldPage.outTransitionEnded += new EventHandler(oldPage_outTransitionEnded);
            oldPage.beginOutTransition();
        }

        void oldPage_outTransitionEnded(object sender, EventArgs e)
        {
            OldScreenContainer.Children.Clear();
            OldScreenContainer.Children.Add((UserControl)NewScreen);
            NewScreen.beginInTransition();

        }


    }

For Example, lets say my root visual is called Border1 and is now containg a child called Screen1 which have a Button called Button1. when the button is clicked i want to switch to Screen2 , so i will put a SwitchScreensBehavior on Button1 with Border1 as OldScreenContainer property and Screen2 as NewScreen property.

This code compiles. I see this Behavior in Blend and can drag it onto a button. But how can i set the two properties of the behavior ? Blend shows me them but I can't figure how to point them to the new screen and to the container ( and what if the new screen is created in runtime) . So I tried to define those properties through the XAML , and again and don't know how to do it. Maybe define them in-code ?

Or maybe this functionality is to big for a Behavior and other elegant solution exists (which relies on as much XMAL as possible) ?


You can bind values of dependency properties in XAML, so what I'd do is to pick the Panel in Blend and bind the other screen via the ViewModel. So in your behavior you'd end up with something like:

OldScreenContainer="{Binding ElementName=MyPanel}" NewScreen="{Binding MyNewScreen}"

This is how you can bind in Blend after clicking on the small rectangle to the right of the property field:

Manage screen transitions with behaviors in silverlight

To be able to reference a UserControl you might have to create a ViewModel and set it as DataContext, at least I can't think of any easier / cleaner way to do it at the moment. Actually, wait, do you have those screens added in your XAML? Could you perhaps paste in your main XAML to your question?

Let me know if that's clear or you need any clarification!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜