Автор работы: Пользователь скрыл имя, 19 Октября 2012 в 19:18, реферат
Что собой представляют пользовательские элементы в WPF
Хотя пользовательский элемент можно построить в любом проекте WPF, обычно такие элементы размещаются в специально выделенной сборке — библиотеке классов (DLL). Это позволяет разделять работу с множеством приложений WPF.
Связывание элементов
После построения совершенного шаблона элемента управления следует позаботиться о внутренних механизмах FlipPanel, чтобы заставить его работать должным образом.
Секрет кроется в методе OnAppl
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
ToggleButton flipButton = base.GetTemplateChild("
if (flipButton != null) flipButton.Click += flipButton_Click;
ToggleButton flipButtonAlternate = base.GetTemplateChild("
if (flipButtonAlternate != null)
flipButtonAlternate.Click += flipButton_Click;
this.ChangeVisualState(false);
}
При вызове GetTemplateChild() необ
Ниже приведен очень простой обработчик события, который позволяет пользователю щелкать на ToggleButton и переворачивать панель:
private void flipButton_Click(object sender, RoutedEventArgs e)
{
this.IsFlipped = !this.IsFlipped;
}
К счастью, вручную инициировать
анимации состояния не понадобится.
Точно также не нужно создавать
или инициировать анимации переходов.
Для смены одного состояния на
другое вызывается статический методVisualStateManager.
При этом передается ссылка на объект элемента управления, состояние которого изменяется, имя нового состояния и булевское значение, определяющее, нужно ли показывать переход. Это значение должно быть true, если речь идет об инициированном пользователем изменении (например, когда пользователь щелкает на ToggleButton), и false — когда речь идет об установке свойства (например, при установке начального значения свойства IsFlipped в разметке страницы).
Поддержка различных состояний
элемента управления может быть запутанной.
Чтобы избежать засорения кода элемента
управления множественными вызовами GoToState(),
в большинстве элементов
Вот как выглядит код метода ChangeVisualState() для FlipPanel:
private void ChangeVisualState(bool useTransitions)
{
if (!this.IsFlipped)
{
VisualStateManager.GoToState(
}
else
{
VisualStateManager.GoToState(
}
// Disable flipped side to prevent tabbing to invisible buttons.
UIElement front = FrontContent as UIElement;
if (front != null)
{
if (IsFlipped)
{
front.Visibility = Visibility.Hidden;
}
else
{
front.Visibility = Visibility.Visible;
}
}
UIElement back = BackContent as UIElement;
if (back != null)
{
if (IsFlipped)
{
back.Visibility = Visibility.Visible;
}
else
{
back.Visibility = Visibility.Hidden;
}
}
}
Обычно метод ChangeVisualState() (или его эквивалент) вызывается в следующих местах:
Как было сказано, элемент управления FlipPanel замечательно гибок. Например, его можно использовать без кнопки ToggleButton и переключать программно (например, когда пользователь щелкает на каком-то другом элементе управления). Кроме того, можно поместить одну или две кнопки переключения в шаблон элемента и предоставить пользователю возможность управлять ими.
Использование FlipPanel
Завершив с шаблоном элемента
управления и кодом FlipPanel, можно приступить
к его использованию в
xmlns:flip="clr-namespace:
После этого можно добавлять экземпляры FlipPanel на страницу. Ниже приведен пример, в котором создается панель FlipPanel, показанная ранее, с использованием контейнера StackPanel для наполнения элементами области содержимого переднего плана и Grid — для заднего:
<flip:FlipPanel x:Name="panel" BorderBrush="DarkOrange"
BorderThickness="3" CornerRadius="4" Margin="10">
<flip:FlipPanel.FrontContent>
<StackPanel Margin="6">
<StackPanel.Resources>
<Style TargetType="Button">
</Style>
</StackPanel.Resources>
<TextBlock TextWrapping="Wrap" FontSize="16" Foreground="DarkOrange">
Это передняя сторона элемента FlipPanel
</TextBlock>
<Button>Первая кнопка</Button>
<Button>Вторая кнопка</Button>
<Button>Третья кнопка</Button>
<Button>Четвертая кнопка</
</StackPanel>
</flip:FlipPanel.FrontContent>
<flip:FlipPanel.BackContent>
<Grid Margin="6">
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition></
</Grid.RowDefinitions>
<TextBlock TextWrapping="Wrap" FontSize="16" Foreground="DarkOrange">
Это обратная сторона элемента управления FlipPanel
</TextBlock>
<Button Grid.Row="1" Margin="3" Padding="10" Content="Перевернуть назад?"
</Grid>
</flip:FlipPanel.BackContent>
</flip:FlipPanel>
Щелчок на кнопке на задней стороне FlipPanel приводит к программному перевороту панели:
private void Button_Click(object sender, RoutedEventArgs e)
{
panel.IsFlipped = !panel.IsFlipped;
}
Это дает тот же результат, что и щелчок на кнопке ToggleButton со стрелкой, которая определена как часть шаблона по умолчанию.
Использование другого шаблона элемента управления
Правильно спроектированные пользовательские элементы управления исключительно гибкие. В случае FlipPanel можно просто применить новый шаблон для изменения внешнего вида и расположения ToggleButton, а также анимационных эффектов, используемых при переключении между передней и задней областями содержимого.
Ниже показан такой
пример. Здесь кнопка помещена в
специальную линейку, находящуюся
внизу фронтальной стороны и
в верхней части обратной стороны.
Когда панель переворачивается, она
делает это не так, как лист бумаги.
Вместо этого содержимое передней панели
просто исчезает, сдвигаясь вверх, при
этом снизу одновременно "выезжает"
содержимое обратной стороны. Когда
происходит противоположное
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{
CornerRadius="{TemplateBinding CornerRadius}"
Background="{TemplateBinding Background}">
<Border.RenderTransform>
<ScaleTransform x:Name="FrontContentTransform"
</Border.RenderTransform>
<Border.Effect>
<BlurEffect x:Name="FrontContentEffect" Radius="0"></BlurEffect>
</Border.Effect>
<Grid>
<Grid.RowDefinitions>
<RowDefinition></
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<ContentPresenter
Content="{TemplateBinding FrontContent}">
</ContentPresenter>
<Rectangle Grid.Row="1" Stretch="Fill" Fill="LightSteelBlue"></
<ToggleButton Grid.Row="1" x:Name="FlipButton" Margin="5" Padding="15,0"
Content="˄" FontWeight="Bold" FontSize="12" HorizontalAlignment="Right">
</ToggleButton>
</Grid>
</Border>
Область содержимого обратной стороны почти такая же. Она включает элемент Border, в котором имеется ContentPresenter с собственной кнопкой ToggleButton, расположенной в правой части текстурированного прямоугольника. Также определены необходимая трансформация ScaleTransform и эффект BlurEffect, которые используются анимацией для смены панелей.
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{
CornerRadius="{TemplateBinding CornerRadius}"
Background="{TemplateBinding Background}" RenderTransformOrigin="0,1">
<Border.RenderTransform>
<ScaleTransform x:Name="BackContentTransform" ScaleY="0"></ScaleTransform>
</Border.RenderTransform>
<Border.Effect>
<BlurEffect x:Name="BackContentEffect" Radius="30"></BlurEffect>
</Border.Effect>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition></
</Grid.RowDefinitions>
<Rectangle Stretch="Fill" Fill="LightSteelBlue"></
<ToggleButton x:Name="FlipButtonAlternate" Margin="5" Padding="15,0"
Content="˅" FontWeight="Bold" FontSize="12" HorizontalAlignment="Right">
</ToggleButton>
<ContentPresenter Grid.Row="1"