WPF: пользовательские элементы

Автор работы: Пользователь скрыл имя, 19 Октября 2012 в 19:18, реферат

Описание

Что собой представляют пользовательские элементы в WPF
Хотя пользовательский элемент можно построить в любом проекте WPF, обычно такие элементы размещаются в специально выделенной сборке — библиотеке классов (DLL). Это позволяет разделять работу с множеством приложений WPF.

Работа состоит из  1 файл

Реферат WPF.docx

— 194.52 Кб (Скачать документ)

Чтобы заполнить переднюю и заднюю области содержимого, FlipPanel использует ContentPresenter. Это почти такой  же прием, который применялся в примере  с пользовательской кнопкой, за исключением  того, что здесь нужны два элемента ContentPresenter, по одному для каждой стороны FlipPanel. Элемент FlipPanel также включает отдельный элемент Border, в который  помещен каждый ContentPresenter.

Это позволяет потребителю  элемента управления определить переворачиваемую область содержимого, устанавливая несколько простых свойств в FlipPanel (BorderBrush, BorderThickness, Background и CornerRadius), вместо того, чтобы добавлять Border вручную.

Ниже показана базовая  структура шаблона элемента управления по умолчанию:

<Style TargetType="{x:Type local:FlipPanel}">

        <Setter Property="Template">

            <Setter.Value>

                <ControlTemplate TargetType="{x:Type local:FlipPanel}">

                    <Grid>

                        <Grid.RowDefinitions>

                            <RowDefinition Height="auto"></RowDefinition>

                            <RowDefinition Height="auto"></RowDefinition>

                        </Grid.RowDefinitions>

                        <!-- Передняя область -->

                        <Border Background="{TemplateBinding Background}" x:Name="FrontContent"

                            BorderBrush="{TemplateBinding BorderBrush}"

                            BorderThickness="{TemplateBinding BorderThickness}"

                            CornerRadius="{TemplateBinding CornerRadius}">

                            <ContentPresenter Content="{TemplateBinding FrontContent}"></ContentPresenter>

                        </Border>

                        <!-- Задняя область -->

                        <Border Background="{TemplateBinding Background}" x:Name="BackContent"

                            BorderBrush="{TemplateBinding BorderBrush}"

                            BorderThickness="{TemplateBinding BorderThickness}"

                            CornerRadius="{TemplateBinding CornerRadius}">

                            <ContentPresenter Content="{TemplateBinding BackContent}"></ContentPresenter>

                        </Border>

                        <!-- Кнопка -->

                        <ToggleButton Grid.Row="1" x:Name="FlipButton" Margin="0,10,0,0" Width="19"

                                      Height="19">

                        </ToggleButton>

                    </Grid>

                </ControlTemplate>

            </Setter.Value>

        </Setter>

    </Style>

При создании шаблона элемента управления по умолчанию лучше избегать жесткого кодирования деталей, которые  потребитель этого элемента может  захотеть настроить по-своему. Вместо этого необходимо применять выражения  привязки шаблонов. В рассматриваемом  примере устанавливаются несколько  свойств с использованием выражений  привязки шаблона: BorderBrush, BorderThickness, CornerRadius, Background, FrontContent и BackContent. Чтобы установить значения по умолчанию для этих свойств, понадобится добавить дополнительные средства установки к стилю по умолчанию элемента управления.

Кнопка переворачивания

Показанный в предыдущем примере шаблон элемента управления включает ToggleButton. Однако в результате он использует внешний вид ToggleButton, т.е. кнопка выглядит как совершенно обычная, с традиционным текстурированным фоном. Для FlipPanel это не подходит.

Хотя можно поместить  внутри ToggleButton любое содержимое, FlipPanel требует немного большего. Вместо стандартного фона необходимо менять внешность элементов внутри в  зависимости от состояния ToggleButton. Как  было показано на рисунке, кнопка ToggleButton определяет способ "переворачивания" содержимого (первоначально стрелка  вправо, когда отображается лицевая  сторона, и стрелка влево, когда  отображается изнанка). Это помогает яснее понять назначение кнопки.

Чтобы создать этот эффект, нужно спроектировать специальный  шаОлон элемента управления для ToggleButton. Этот шаблон элемента управления может  включать элементы-фигуры, которые  рисуют нужные стрелки. В данном примере ToggleButton рисуется с помощью элемента Ellipse (отображает кружок) и элемента Path (для стрелки), и оба они помещаются в Grid из одной ячейки. Для ToggleButton требуется  еще одна деталь — трансформация RotateTransform, которая поворачивает стрелку  с одной стороны в другую. Эта RotateTransform будет использоваться при  создании анимаций состояния:

<ToggleButton Grid.Row="1" x:Name="FlipButton" Margin="0,10,0,0" Width="19"

                                      Height="19" RenderTransformOrigin="0.5,0.5">

      <ToggleButton.Template>

            <ControlTemplate>

                   <Grid>

                        <Ellipse Stroke="#FFA9A9A9" Fill="AliceBlue"></Ellipse>

                        <Path Data="M1,1.5L4.5,5 8,1.5" Stroke="#FF666666" StrokeThickness="2"

                                HorizontalAlignment="Center" VerticalAlignment="Center"></Path>

                  </Grid>

            </ControlTemplate>

      </ToggleButton.Template>

      <ToggleButton.RenderTransform>

              <RotateTransform x:Name="FlipButtonTransform" Angle="-90"></RotateTransform>

      </ToggleButton.RenderTransform>

</ToggleButton>

Определение анимаций состояния

Анимации  состояния — наиболее интересная часть шаблона элемента управления. Они являются ингредиентами, которые обеспечивают поведение "переворачивания". Кроме того, это детали, которые наиболее вероятно будут изменяться, если разработчик создаст специальный шаблон для FlipPanel.

Для определения групп  состояний понадобится добавить элемент VisualStateManager.VisualStateGroups в корневой узел шаблона элемента управления.

Чтобы к шаблону можно  было добавить элемент VisualStateManager, шаблон должен использовать панель компоновки. Эта панель компоновки содержит оба  объекта Visual для элемента управления и невидимый VisualStateManager. Диспетчер VisualStateManager определяет раскадровки с анимациями, которые может применять элемент управления, чтобы в надлежащий момент изменять свой внешний вид.

Внутри элемента VisualStateManager можно создавать группы состояний, используя соответствующим образом  именованные элементы VisualStateGroup. В  каждую группу VisualStateGroup добавляется  элемент VisualState для каждого визуального  состояния. В случае FlipPanel имеется  одна группа, которая содержит два  визуальных состояния.

Каждое состояние соответствует  раскадровке с одной или более  анимадиями. Если эти раскадровки  существуют, они инициируются в соответствующие  моменты времени. (Если нет, то элемент  управления не должен генерировать ошибку.)

В шаблоне элемента управления, принятом по умолчанию, анимации используют простое затухание для перехода от одной области содержимого  к другой, и вращение для переключения стрелки ToggleButton, чтобы она указывала  в другом направлении. Ниже показана разметка, которая решает обе задачи:

<VisualStateManager.VisualStateGroups>

                            <VisualStateGroup x:Name="ViewStates">

                                <VisualState x:Name="Normal">

                                    <Storyboard>

                                        <DoubleAnimation Storyboard.TargetName="BackContent"

                                                         Storyboard.TargetProperty="Opacity"

                                                         To="0" Duration="0"></DoubleAnimation>

                                    </Storyboard>

                                </VisualState>

                                <VisualState x:Name="Flipped">

                                    <Storyboard>

                                        <DoubleAnimation Storyboard.TargetName="FlipButtonTransform"

                                                         Storyboard.TargetProperty="Angle"

                                                         To="90" Duration="0"></DoubleAnimation>

                                        <DoubleAnimation Storyboard.TargetName="FrontContent"

                                                         Storyboard.TargetProperty="Opacity"

                                                         To="0" Duration="0"></DoubleAnimation>

                                    </Storyboard>

                                </VisualState>

                            </VisualStateGroup>

                        </VisualStateManager.VisualStateGroups>

Обратите внимание, что  визуальные состояния устанавливают  нулевую длительность анимации, а  это значит, что анимация оставляет  свой эффект в силе на постоянной основе. Это может показаться странным —  в конце концов, разве не нужно  более постепенное изменение, чтобы заметить анимационный эффект?

В действительности такое  проектное решение совершенно корректно, потому что визуальные состояния  предназначены для определения  внешности элемента управления, когда  он находится в соответствующем  состоянии. Например, перевернутая панель просто показывает свое фоновое содержимое, пока находится в перевернутом состоянии.

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

Переходы между  состояниями

Переход (transition) — это анимация, которая начинается с текущего состояния и заканчивается новым состоянием. Одно из преимуществ модели переходов состоит в том, что создавать раскадровку для этой анимации не придется.

Переходы применяются  к группам состояний. После определения  переход должен быть добавлен в коллекциюVisualStateGroup.Transitions. Переход по умолчанию удобен, но это "универсальное" решение, которое не всегда подходит. Например, может понадобиться, чтобы переходы FlipPanel происходили с разной скоростью, в зависимости от того, к какому состоянию они применяются. Чтобы настроить это, необходимо определить множество переходов и устанавливать свойство То для указания момента начала перехода.

Для еще более тонкого  контроля можно создавать специальные  анимации переходов, которые заменяют собой автоматически сгенерированные  переходы, обычно используемые WPF. Причин создания специальных переходов  несколько: управление ходом анимации; использование функций плавности  анимации; последовательный запуск нескольких анимаций; воспроизведение звука  одновременно с анимацией.

Чтобы определить специальный  переход, внутрь элемента VisualTransition помещается раскадровка с одной или более  анимациями. В примере с FlipPanel специальные  переходы можно использовать для  обеспечения быстрого поворота кнопки ToggleButton, но при более плавном затухании переворачиваемой области:

<VisualStateGroup.Transitions>

                 <VisualTransition GeneratedDuration="0:0:0.7" To="Flipped">

                             <Storyboard>

                                     <DoubleAnimation Storyboard.TargetName="FlipButtonTransform"

                                                             Storyboard.TargetProperty="Angle"

                                                             To="90" Duration="0:0:0.2"></DoubleAnimation>

                             </Storyboard>

                </VisualTransition>

                <VisualTransition GeneratedDuration="0:0:0.7" To="Normal">

                             <Storyboard>

                                    <DoubleAnimation Storyboard.TargetName="FlipButtonTransform"

                                                             Storyboard.TargetProperty="Angle"

                                                             To="-90" Duration="0:0:0.2"></DoubleAnimation>

                             </Storyboard>

               </VisualTransition>

    </VisualStateGroup.Transitions>

При использовании специального перехода все равно необходимо устанавливать свойствоVisualTransition.GeneratedDuration для задания длительности анимации. Без этой детали VisualStateManager не сможет использовать переход и переключит элемент в новое состояние немедленно. (Действительное значение времени не оказывает влияния на специальный переход, потому что применяется только к автоматически генерированным анимациям.)

К сожалению, многие элементы управления требуют специальных  переходов, написание которых утомительно. Все равно придется сохранить  некоторые анимации состояния нулевой  длины, что также приводит к некоторому неизбежному дублированию деталей  между визуальными состояниями  и переходами.

Информация о работе WPF: пользовательские элементы