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

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

Описание

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

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

Реферат WPF.docx

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

Связывание элементов

После построения совершенного шаблона элемента управления следует  позаботиться о внутренних механизмах FlipPanel, чтобы заставить его работать должным образом.

Секрет кроется в методе OnApplyTemplate(), который также использовался для установки привязок ColorPicker. Метод OnApplyTemplate() для FlipPanel извлекает кнопку ToggleButton для частей FlipButton и FlipButtonAlternate, и присоединяет обработчики событий к каждой из них, чтобы они могли реагировать на щелчки для переворачивания элемента управления. Метод OnApplyTemplate() завершается вызовом специального метода ChangeVisualState(), который обеспечивает соответствие визуального представления элемента управления его текущему состоянию:

public override void OnApplyTemplate()

        {

            base.OnApplyTemplate();

            ToggleButton flipButton = base.GetTemplateChild("FlipButton") as ToggleButton;

            if (flipButton != null) flipButton.Click += flipButton_Click;

 

            ToggleButton flipButtonAlternate = base.GetTemplateChild("FlipButtonAlternate") as ToggleButton;

            if (flipButtonAlternate != null)

                flipButtonAlternate.Click += flipButton_Click;

 

            this.ChangeVisualState(false);

        }

При вызове GetTemplateChild() необходимо указать строковое имя нужного элемента. Во избежание возможных ошибок, эту строку можно объявить константной в элементе управления. Затем эту константу можно использовать в атрибуте TemplatePart и при вызове GetTemplateChild().

Ниже приведен очень простой  обработчик события, который позволяет  пользователю щелкать на ToggleButton и  переворачивать панель:

private void flipButton_Click(object sender, RoutedEventArgs e)

{

   this.IsFlipped = !this.IsFlipped;

}

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

При этом передается ссылка на объект элемента управления, состояние  которого изменяется, имя нового состояния  и булевское значение, определяющее, нужно ли показывать переход. Это  значение должно быть true, если речь идет об инициированном пользователем изменении (например, когда пользователь щелкает  на ToggleButton), и false — когда речь идет об установке свойства (например, при  установке начального значения свойства IsFlipped в разметке страницы).

Поддержка различных состояний  элемента управления может быть запутанной. Чтобы избежать засорения кода элемента управления множественными вызовами GoToState(), в большинстве элементов добавляется  специальный метод, подобный ChangeVisualState() в FlipPanel. Этот метод отвечает за применение корректного состояния к каждой группе состояний. Код внутри него использует блок if (или оператор switch) для применения текущего состояния к каждой группе. Такой подход работает, поскольку  вполне допустимо вызывать GoToState() с именем текущего состояния. В ситуации, когда текущее состояние и запрошенное состояние совпадают, ничего не происходит.

Вот как выглядит код метода ChangeVisualState() для FlipPanel:

private void ChangeVisualState(bool useTransitions)

        {

            if (!this.IsFlipped)

            {               

                VisualStateManager.GoToState(this, "Normal", useTransitions);

            }

            else

            {

                VisualStateManager.GoToState(this, "Flipped", useTransitions);               

            }

 

            // 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() (или его эквивалент) вызывается в следующих местах:

  • После инициализации элемента управления в конце метода OnApplyTemplate().
  • При реагировании на событие, которое представляет изменение состояния, такое как перемещение курсора мыши или щелчок на ToggleButton.
  • При реагировании на изменение свойства или на метод, который вызывается в коде. (Например, средство установки свойства IsFlipped вызывает ChangeVisualState() и всегда передает true, тем самым вызывая показ анимаций переходов. Чтобы предоставить потребителю элемента управления выбор, показывать переход или нет, можно добавить метод Flip(), который принимает тот же самый булевский параметр, который передается методу ChangeVisualState().)

Как было сказано, элемент  управления FlipPanel замечательно гибок. Например, его можно использовать без кнопки ToggleButton и переключать  программно (например, когда пользователь щелкает на каком-то другом элементе управления). Кроме того, можно поместить  одну или две кнопки переключения в шаблон элемента и предоставить пользователю возможность управлять  ими.

Использование FlipPanel

Завершив с шаблоном элемента управления и кодом FlipPanel, можно приступить к его использованию в приложениях. Исходя из предположения, что добавлена  необходимая ссылка на сборку, следует  отобразить префикс XML на пространство имен, которое хранит специальный  элемент управления:

xmlns:flip="clr-namespace:WpfCustomControlLibrary1;assembly=WpfCustomControlLibrary1"

После этого можно добавлять  экземпляры 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">

                                <Setter Property="Padding" Value="5"></Setter>

                                <Setter Property="Margin" Value="5,5,5,0"></Setter>

                            </Style>

                        </StackPanel.Resources>

                        <TextBlock TextWrapping="Wrap" FontSize="16" Foreground="DarkOrange">

                            Это передняя сторона элемента FlipPanel

                        </TextBlock>

                        <Button>Первая кнопка</Button>

                        <Button>Вторая кнопка</Button>

                        <Button>Третья кнопка</Button>

                        <Button>Четвертая кнопка</Button>

                    </StackPanel>

                </flip:FlipPanel.FrontContent>

                <flip:FlipPanel.BackContent>

                    <Grid Margin="6">

                        <Grid.RowDefinitions>

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

                            <RowDefinition></RowDefinition>

                        </Grid.RowDefinitions>

                        <TextBlock TextWrapping="Wrap" FontSize="16" Foreground="DarkOrange">

                            Это обратная сторона элемента управления FlipPanel

                        </TextBlock>

                        <Button Grid.Row="1" Margin="3" Padding="10" Content="Перевернуть назад?"

                                HorizontalAlignment="Center" VerticalAlignment="Center"

                                Click="Button_Click"></Button>

                    </Grid>

                </flip:FlipPanel.BackContent>

</flip:FlipPanel>

Щелчок на кнопке на задней стороне FlipPanel приводит к программному перевороту панели:

private void Button_Click(object sender, RoutedEventArgs e)

{

    panel.IsFlipped = !panel.IsFlipped;

}

Это дает тот же результат, что и щелчок на кнопке ToggleButton со стрелкой, которая определена как  часть шаблона по умолчанию.

Использование другого  шаблона элемента управления

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

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

<Border BorderBrush="{TemplateBinding BorderBrush}"

               BorderThickness="{TemplateBinding BorderThickness}"

               CornerRadius="{TemplateBinding CornerRadius}"

                            Background="{TemplateBinding Background}">

                    <Border.RenderTransform>

                        <ScaleTransform x:Name="FrontContentTransform"></ScaleTransform>

                    </Border.RenderTransform>

                    <Border.Effect>

                        <BlurEffect x:Name="FrontContentEffect" Radius="0"></BlurEffect>

                    </Border.Effect>

 

                    <Grid>

                        <Grid.RowDefinitions>

                            <RowDefinition></RowDefinition>

                            <RowDefinition Height="Auto"></RowDefinition>

                        </Grid.RowDefinitions>

                        <ContentPresenter

                     Content="{TemplateBinding FrontContent}">

                        </ContentPresenter>

 

                        <Rectangle Grid.Row="1" Stretch="Fill" Fill="LightSteelBlue"></Rectangle>

                        <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="{TemplateBinding 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></RowDefinition>

                        </Grid.RowDefinitions>

 

                        <Rectangle Stretch="Fill" Fill="LightSteelBlue"></Rectangle>

                        <ToggleButton x:Name="FlipButtonAlternate" Margin="5" Padding="15,0"

                             Content="˅" FontWeight="Bold" FontSize="12" HorizontalAlignment="Right">

                        </ToggleButton>

 

                        <ContentPresenter Grid.Row="1"

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