Управление переходами экрана с помощью поведения в Silverlight - PullRequest
0 голосов
/ 10 марта 2011

Корневая визуализация моего приложения - это панель границ, которая остается неизменной все время.Что делает изменения - это дочерний элемент панели границ: я создал несколько экранов (UserControl) и хочу переключаться между ними при нажатии определенных кнопок на каждом экране.

Я хочу, чтобы переходы между экранами были визуальнопривлекательным, так что на каждом экране будет две StoryBoards, одна для анимации слайдов и одна для анимации слайдов.(Чтобы было понятнее, слайд в анимации экрана1, например, будет перемещать кнопки и поля экрана1 определенным образом в область просмотра, пока они не достигнут своей конечной позиции).

Моя цель - добиться этогопереходы между экранами с поведением и применение их к экранам с как можно меньшим количеством кода (лучше всего будет только 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 - это StoryBoards, которые я создал с помощью Blend для каждого экрана.

Теперь я хочу написатьПоведение для управления переходом.Это поведение будет действовать на кнопку.У него будет два свойства.Одним из них является 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, поэтому я добавлю SwitchScreensBehavior на Button1 с Border1 в качестве свойства OldScreenContainer и Screen2 в качестве свойства NewScreen.

Этот код компилируется.Я вижу это поведение в Blend и могу перетащить его на кнопку.Но как я могу установить два свойства поведения?Смесь показывает мне их, но я не могу понять, как указать их на новый экран и контейнер (и что, если новый экран создается во время выполнения).Поэтому я попытался определить эти свойства через XAML, и снова, и не знаю, как это сделать.Может быть, определить их в коде?

Или, может быть, эта функциональность слишком велика для поведения, и существует другое элегантное решение (которое использует как можно больше XMAL)?

1 Ответ

0 голосов
/ 10 марта 2011

Вы можете связать значения свойств зависимостей в XAML, поэтому я бы выбрал Panel в Blend и связал другой экран через ViewModel.Таким образом, в вашем поведении вы получите что-то вроде:

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

Вот как вы можете связать в Blend после нажатия на маленький прямоугольник справа от поля свойства:

This is how you bind in Blend

Чтобы иметь возможность ссылаться на UserControl, вам, возможно, придется создать ViewModel и установить его как DataContext, по крайней мере, я не могу придумать более простой / понятный способ сделать это в данный момент.На самом деле, подождите, у вас есть эти экраны, добавленные в ваш XAML?Не могли бы вы вставить в свой основной XAML свой вопрос?

Дайте мне знать, если это понятно, или вам нужны какие-либо разъяснения!

...