私のアプリ ルート ビジュアルは、常に固定されたままのボーダー パネルです。変更内容は、ボーダー パネルの子です。いくつかの画面 (UserControl) を作成しましたが、各画面内の特定のボタンがクリックされたときにそれらを切り替えたいと考えています。
各画面に 2 つの StoryBoards があり、1 つはスライド イン アニメーション用で、もう 1 つはスライド アウト アニメーション用です。(より明確にするために、たとえば、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 です。
ここで、遷移を管理するための動作を書きたいと思います。この動作はボタンで動作します。2 つのプロパティを持つことになります。1 つは、Panel タイプの OldScreenContainer で、削除する画面のコンテナーを表します。2 番目は IScreenWithTransitions 型の NewScreen で、コンテナー内に配置する新しい画面を表します。
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 で、現在、Button1 というボタンを持つ Screen1 という子が含まれているとします。ボタンがクリックされたときに Screen2 に切り替えたいので、Border1 を OldScreenContainer プロパティとして、Screen2 を NewScreen プロパティとして Button1 に SwitchScreensBehavior を配置します。
このコードはコンパイルされます。Blend でこの動作を確認し、ボタンにドラッグできます。しかし、どうすれば動作の 2 つのプロパティを設定できますか? Blendはそれらを表示しますが、それらを新しい画面とコンテナに向ける方法がわかりません(新しい画面が実行時に作成された場合)。そのため、 XAML を使用してこれらのプロパティを定義しようとしましたが、その方法がわかりません。多分それらをコード内で定義しますか?
それとも、この機能が動作に対して大きすぎて、他の洗練されたソリューションが存在する可能性があります (可能な限り多くの XMAL に依存しています)。