使用silverlight中的行为管理屏幕转换

时间:2011-03-10 11:44:11

标签: c# silverlight animation behavior transitions

我的app root visual是一个边框面板,它始终保持固定状态。 边框面板的子项有什么变化:我已经制作了几个屏幕(UserControl),并且当点击每个屏幕中的某些按钮时想要在它们之间切换。

我希望屏幕之间的过渡具有视觉吸引力,这样每个屏幕都会有两个StoryBoards,一个用于动画幻灯片,另一个用于幻灯片动画。 (为了更清楚,例如,screen1的动画幻灯片将以特定的方式将screen1的按钮和字段移动到视图区域,直到它们到达最终位置。)

我的目标是使用行为实现这些屏幕转换,并将它们应用于尽可能少的代码(最好只是XAML)。

首先,我定义了一个新界面,我的所有应用程序屏幕都会实现:

public interface IScreenWithTransitions
    {
        void beginOutTransition();

        void beginInTransition();

        event EventHandler outTransitionEnded;
    }

然后后面的screen1代码将如下所示:

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和AnimationIn是我使用Blend为每个屏幕创建的StoryBoards。

现在,我想编写一个行为来管理转换。此行为将作用于Button。它将有两个属性。一个是OldScreenContainer,它是Panel类型,代表我们要删除的屏幕的容器。其次是NewScreen,它是IScreenWithTransitions类型,代表我们想要放入容器的新屏幕。

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();

        }


    }

例如,假设我的root visual名为Border1,现在正在包含一个名为Screen1的子项,它有一个名为Button1的Button。当单击按钮时我想切换到Screen2,所以我将在Button1上放置一个SwitchScreensBehavior,其中Border1为OldScreenContainer属性,Screen2为NewScreen属性。

此代码编译。我在Blend中看到了这个行为,可以将它拖到一个按钮上。但是我如何设置行为的两个属性? Blend向我展示了它们,但我无法想象如何将它们指向新的屏幕和容器(如果在运行时创建新屏幕,该怎么办)。所以我尝试通过XAML定义这些属性,并再次不知道如何做到这一点。也许在代码中定义它们?

或许这个功能对于一个行为来说很重要,并且存在其他优雅的解决方案(它依赖于尽可能多的XMAL)?

1 个答案:

答案 0 :(得分:0)

您可以在XAML中绑定依赖项属性的值,因此我要做的是选择Blend中的Panel并通过ViewModel绑定另一个屏幕。所以在你的行为中,你最终会得到类似的东西:

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

这是在单击属性字段右侧的小矩形后可以在Blend中绑定的方法:

This is how you bind in Blend

为了能够引用UserControl,您可能必须创建一个ViewModel并将其设置为DataContext,至少我想不出任何更简单/更清晰的方法来实现它。实际上,等等,你的XAML中是否添加了这些屏幕?您可以将主XAML粘贴到您的问题中吗?

如果清楚或者您需要澄清,请告诉我!