我的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)?
答案 0 :(得分:0)
您可以在XAML中绑定依赖项属性的值,因此我要做的是选择Blend中的Panel并通过ViewModel绑定另一个屏幕。所以在你的行为中,你最终会得到类似的东西:
OldScreenContainer="{Binding ElementName=MyPanel}" NewScreen="{Binding MyNewScreen}"
这是在单击属性字段右侧的小矩形后可以在Blend中绑定的方法:
为了能够引用UserControl,您可能必须创建一个ViewModel并将其设置为DataContext,至少我想不出任何更简单/更清晰的方法来实现它。实际上,等等,你的XAML中是否添加了这些屏幕?您可以将主XAML粘贴到您的问题中吗?
如果清楚或者您需要澄清,请告诉我!