0

我的应用程序根视觉是一个始终保持固定的边框面板。改变的是边框面板的子项:我制作了几个屏幕(UserControl),并希望在单击每个屏幕中的某些按钮时在它们之间切换。

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

我的目标是使用 Behavior 实现这些屏幕转换,并将它们应用到代码尽可能少的屏幕上(最好只使用 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 为每个屏幕创建的 StoryBoard。

现在,我想编写一个行为来管理转换。此行为将作用于按钮。它将有两个属性。一个是 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();

        }


    }

例如,假设我的根视觉对象称为 Border1,现在包含一个名为 Screen1 的子对象,该子对象具有一个名为 Button1 的按钮。单击按钮时,我想切换到 Screen2 ,因此我将在 Button1 上放置一个 SwitchScreensBehavior ,将 Border1 作为 OldScreenContainer 属性,将 Screen2 作为 NewScreen 属性。

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

或者这个功能对于行为来说太大了,并且存在其他优雅的解决方案(它尽可能多地依赖 XMAL)?

4

1 回答 1

0

您可以在 XAML 中绑定依赖属性的值,所以我要做的是在 Blend 中选择面板并通过 ViewModel 绑定另一个屏幕。因此,在您的行为中,您最终会得到以下结果:

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

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

这就是您在 Blend 中绑定的方式

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

让我知道这是否清楚或您需要任何澄清!

于 2011-03-10T12:00:41.953 回答