我的应用程序根视觉是一个始终保持固定的边框面板。改变的是边框面板的子项:我制作了几个屏幕(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)?