0

私のアプリ ルート ビジュアルは、常に固定されたままのボーダー パネルです。変更内容は、ボーダー パネルの子です。いくつかの画面 (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 に依存しています)。

4

1 に答える 1

0

XAML で依存関係プロパティの値をバインドできるので、Blend で Panel を選択し、ViewModel を介して他の画面をバインドします。したがって、あなたの行動では、次のような結果になります。

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

これは、プロパティ フィールドの右側にある小さな四角形をクリックした後、Blend でバインドする方法です。

これが Blend でバインドする方法です

UserControl を参照できるようにするには、ViewModel を作成して DataContext として設定する必要があるかもしれませんが、少なくとも現時点では、より簡単でクリーンな方法は考えられません。実際のところ、XAML にそれらの画面が追加されていますか? メインの XAML を質問に貼り付けていただけませんか?

それが明確な場合、または明確化が必要な場合はお知らせください。

于 2011-03-10T12:00:41.953 に答える