Корневая визуализация моего приложения - это панель границ, которая остается неизменной все время.Что делает изменения - это дочерний элемент панели границ: я создал несколько экранов (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)?