Рейтинговые книги
Читем онлайн Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 350 351 352 353 354 355 356 357 358 ... 407
кода.

Далее приведена модифицированная разметка для стиля элементов управления типа TextBox, где обеспечивается установка фона желтого цвета, когда элемент TextBox получает фокус:

<!-- Стандартный стиль для всех текстовых полей -->

<Style TargetType="TextBox">

  <Setter Property="FontSize" Value="14"/>

  <Setter Property="Width" Value="100"/>

  <Setter Property="Height" Value="30"/>

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

  <Setter Property="BorderBrush" Value="Red"/>

  <Setter Property="FontStyle" Value="Italic"/>

  <!-- Следующий установщик будет применен, только

       когда текстовое поле находится в фокусе -->

  <Style.Triggers>

    <Trigger Property="IsFocused" Value="True">

      <Setter Property="Background" Value="Yellow"/>

    </Trigger>

  </Style.Triggers>

</Style>

При тестировании этого стиля вы обнаружите, что по мере перехода с помощью клавиши <ТаЬ> между элементами TextBox текущий выбранный TextBox получает фон желтого цвета (если только стиль не отключен путем присваивания {x:Null} свойству Style).

Триггеры свойств также весьма интеллектуальны в том смысле, что когда условие триггера не истинно, то свойство автоматически получает стандартное значение. Следовательно, как только TextBox теряет фокус, он также автоматически принимает стандартный цвет без какой-либо работы с вашей стороны. По контрасту с ними триггеры событий (которые исследовались при рассмотрении анимации WPF) не возвращаются автоматически в предыдущее состояние.

Определение стилей с множеством триггеров

Триггеры могут быть спроектированы так, что определенные элементы Setter будут применяться, когда истинными должны оказаться многие условия. Пусть необходимо устанавливать фон элемента TextBox в Yellow только в случае, если он имеет активный фокус и курсор мыши находится внутри его границ. Для этого можно воспользоваться элементом MultiTriggern определить в нем каждое условие:

<!-- Стандартный стиль для всех текстовых полей -->

<Style TargetType="TextBox">

  <Setter Property="FontSize" Value="14"/>

  <Setter Property="Width" Value="100"/>

  <Setter Property="Height" Value="30"/>

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

  <Setter Property="BorderBrush" Value="Red"/>

  <Setter Property="FontStyle" Value="Italic"/>

  <!-- Следующий установщик будет применен, только когда текстовое

       поле имеет фокус И над ним находится курсор мыши -->

  <Style.Triggers>

    <MultiTrigger>

      <MultiTrigger.Conditions>

          <Condition Property="IsFocused" Value="True"/>

          <Condition Property="IsMouseOver" Value="True"/>

      </MultiTrigger.Conditions>

      <Setter Property="Background" Value="Yellow"/>

    </MultiTrigger>

  </Style.Triggers>

</Style>

Стили с анимацией

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

<!-- Стиль увеличивающейся кнопки -->

<Style x:Key="GrowingButtonStyle" TargetType="Button">

  <Setter Property="Height" Value="40"/>

  <Setter Property="Width" Value="100"/>

  <Style.Triggers>

    <Trigger Property="IsMouseOver" Value="True">

      <Trigger.EnterActions>

        <BeginStoryboard>

          <Storyboard TargetProperty="Height">

            <DoubleAnimation From="40" To="200"

                Duration="0:0:2" AutoReverse="True"/>

          </Storyboard>

        </BeginStoryboard>

      </Trigger.EnterActions>

    </Trigger>

  </Style.Triggers>

</Style>

Здесь коллекция Triggers наблюдает за тем, когда свойство IsMouseOver возвратит значение true. После того как это произойдет, определяется элемент Trigger.EnterActions для выполнения простой раскадровки, которая заставляет кнопку за две секунды увеличиться до значения Height, равного 200 (и затем возвратиться к значению Height, равному 40). Чтобы отслеживать другие изменения свойств, можно также добавить область Trigger.ExitActions и определить в ней любые специальные действия, которые должны быть выполнены, когда IsMouseOver изменяется на false.

Применение стилей в коде

Вспомните, что стиль может применяться также во время выполнения. Прием удобен, когда у конечных пользователей должна быть возможность выбора внешнего вида для их пользовательского интерфейса, требуется принудительно устанавливать внешний вид и поведение на основе настроек безопасности (например, стиль DisableAllButton) или еще в какой-то ситуации.

В текущем проекте было определено порядочное количество стилей, многие из которых могут применяться к элементам управления Button. Давайте переделаем пользовательский интерфейс главного окна, чтобы позволить пользователю выбирать имена имеющихся стилей в элементе управления ListBox. На основе выбранного имени будет применен соответствующий стиль. Вот финальная разметка для элемента DockPanel:

<DockPanel >

  <StackPanel Orientation="Horizontal" DockPanel.Dock="Top" Margin="0,0,0,50">

    <Label Content="Please Pick a Style for this Button" Height="50"/>

    <ListBox x:Name="lstStyles" Height="80" Width="150" Background="LightBlue"

        SelectionChanged="comboStyles_Changed" />

  </StackPanel>

  <Button x:Name="btnStyle" Height="40" Width="100" Content="OK!"/>

</DockPanel>

Элемент управления ListBox (по имени IstStyles) будет динамически заполняться внутри конструктора окна:

public MainWindow()

{

  InitializeComponent();

  // Заполнить окно со списком всеми стилями для элементов Button.

  lstStyles.Items.Add("GrowingButtonStyle");

  lstStyles.Items.Add("TiltButton");

  lstStyles.Items.Add("BigGreenButton");

  lstStyles.Items.Add("BasicControlStyle");}

}

Последней задачей является обработка события SelectionChanged в связанном файле кода. Обратите внимание, что в следующем коде имеется возможность извлечения текущего ресурса по имени с использованием унаследованного метода TryFindResouce():

private void comboStyles_Changed(object sender, SelectionChangedEventArgs e)

{

  // Получить имя стиля, выбранное в окне со списком.

  var currStyle=(Style)TryFindResource(lstStyles.SelectedValue);

  if (currStyle==null) return;

  // Установить стиль для типа кнопки.

  this.btnStyle.Style=currStyle;

}

После запуска приложения появляется возможность выбора одного из четырех стилей кнопок на лету. На рис. 27.9 показано готовое приложение в действии.

Логические деревья, визуальные деревья и стандартные шаблоны

Теперь, когда вы понимаете, что собой представляют стили и ресурсы, есть еще несколько тем, которые потребуется раскрыть, прежде чем приступать к изучению построения специальных элементов управления. В частности, необходимо выяснить разницу между логическим деревом, визуальным деревом и стандартным шаблоном. При вводе разметки XAML в Visual Studio или в редакторе вроде Kaxaml разметка является логическим представлением документа XAML. В случае написания кода С#, который добавляет в элемент управления StackPanel новые элементы, они вставляются в логическое дерево. По существу логическое представление отражает то, как содержимое будет позиционировано внутри разнообразных диспетчеров компоновки для главного элемента Window (или другого корневого элемента, такого как Page или NavigationWindow).

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

1 ... 350 351 352 353 354 355 356 357 358 ... 407
На этой странице вы можете бесплатно читать книгу Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен бесплатно.

Оставить комментарий