Автор Тема: Template, Style, Trigger. Sample #1  (Прочитано 2228 раз)

Sergey

  • Administrator
  • Newbie
  • *****
  • Сообщений: 14
    • Просмотр профиля
Template, Style, Trigger. Sample #1
« : Январь 21, 2013, 12:58:06 am »
Сегодня мы рассмотрим пример, в котором используются стиль, шаблон и триггер (Template, Style and Trigger). Перечисленные инструменты, в большей степени характерные для XAML, позволяют самым удивительным образом настраивать интерфейс пользователя.

Итак, задача будет состоять в том, чтобы настроить классический ToggleButton (кнопка с залипанием). Именно, в зависимости от того, нажата ли кнопка или нет, показывать соответствующий значок.
Инструментарий: Expression Blend, Expression Design, Visual studio.
Expression Design - великолепный графический инструмент для подготовки векторной графики и изображений для последующего использования в проектировании UI - интерфейса пользователя. Самое привлекательное состоит в том, что формат сохранения векторной графики может быть в том числе и XAML с контейнером Canvas и (или) Viewbox. Сочетание последних контейнеров предназначено именно для отображения графики. Если чуть глубже, то в этих контейнерах реализовано адаптированное расположение графических элементов, основанное на их действительных размерах.

Результат представлен рисунком ниже:


Итак, файл кода остается совершенно пустым - все реализуется в XAML. Код экземпляра, унаследованного от Window имеет вид
Код: XML
  1. <Window x:Class="MainWindow"
  2.    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5.    Title="MainWindow" Height="156" Width="291">
  6.         <Window.Resources>
  7.                 <ResourceDictionary>
  8.                         <ResourceDictionary.MergedDictionaries>
  9.                                 <ResourceDictionary Source="TSResources.xaml"/>
  10.                         </ResourceDictionary.MergedDictionaries>
  11.                 </ResourceDictionary>
  12.         </Window.Resources>
  13.     <Grid>
  14.         <Grid.ColumnDefinitions>
  15.             <ColumnDefinition/>
  16.         </Grid.ColumnDefinitions>
  17.         <Grid.RowDefinitions>
  18.             <RowDefinition Height="Auto"/>
  19.             <RowDefinition/>
  20.         </Grid.RowDefinitions>
  21.         <Grid.Background>
  22.             <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
  23.                 <GradientStop Color="Black" Offset="0"/>
  24.                 <GradientStop Color="White" Offset="1"/>
  25.             </LinearGradientBrush>
  26.         </Grid.Background>
  27.         <DockPanel
  28.                   LastChildFill="False"
  29.                   Grid.RowSpan="1"
  30.                   Grid.Row="0"
  31.                   Grid.Column="0">
  32.             <ToggleButton MinWidth="50" MinHeight="30"
  33.                         Style="{StaticResource OpenCloseStyle}">
  34.             </ToggleButton>
  35.             <ToggleButton MinWidth="50" MinHeight="30"
  36.                 Style="{StaticResource OpenCloseStyle}"/>
  37.             <ToggleButton MinWidth="50" MinHeight="30"
  38.                 Style="{StaticResource OpenCloseStyle}"/>
  39.         </DockPanel>
  40.     </Grid>
  41. </Window>
  42.  
Ясно, что вся "основная" работа по настройке вида кнопки происходит в словаре ресурсов - в файле TSResources.xaml.
Его код представлен ниже:
Код: XML
  1. <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  2.    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">  
  3.         <DataTemplate x:Key="ArrowToOpen">
  4.         <Viewbox
  5.                         Height="20" Width="20">
  6.             <Canvas Width="122.717" Height="82.377" Clip="F1 M 0,0L 122.717,0L 122.717,82.377L 0,82.377L 0,0">
  7.                 <Path Width="122.717" Height="82.377" Stretch="Fill" StrokeThickness="2.88" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FFFFFFFF" Data="F1 M 61.172,80.937L 41.5788,61.3659L 2.90447,22.7035C 0.951843,20.7509 0.951843,17.585 2.90447,15.6324L 15.6324,2.9045C 17.585,0.951859 20.7508,0.951859 22.7035,2.9045L 61.2962,41.5235L 100.014,2.9045C 101.966,0.951859 105.132,0.951859 107.085,2.9045L 119.813,15.6324C 121.765,17.585 121.765,20.7508 119.813,22.7034L 81.2563,61.26L 61.172,80.937 Z "/>
  8.             </Canvas>
  9.         </Viewbox>
  10.     </DataTemplate>
  11.     <DataTemplate x:Key="ArrowToClose">
  12.         <Viewbox
  13.                         Height="20" Width="20">
  14.             <Canvas Width="82.377" Height="122.717" Clip="F1 M 0,0L 82.377,0L 82.377,122.717L 0,122.717L 0,0">
  15.                 <Path Width="82.377" Height="122.717" Stretch="Fill" StrokeThickness="2.88" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FFFFFFFF" Data="F1 M 80.937,61.5453L 61.3658,81.1385L 22.7035,119.813C 20.7509,121.765 17.585,121.765 15.6324,119.813L 2.90448,107.085C 0.951843,105.132 0.951843,101.966 2.90448,100.014L 41.5234,61.421L 2.90442,22.7034C 0.951782,20.7507 0.951782,17.585 2.90442,15.6323L 15.6323,2.90442C 17.585,0.951782 20.7508,0.951782 22.7034,2.90442L 61.2599,41.4609L 80.937,61.5453 Z "/>
  16.             </Canvas>
  17.         </Viewbox>
  18.     </DataTemplate>
  19.         <Style x:Key="OpenCloseStyle" TargetType="ToggleButton">
  20.                 <Style.Triggers>
  21.                         <Trigger Property="IsChecked" Value="False">
  22.                                 <Setter Property="ContentTemplate" Value="{StaticResource ArrowToOpen}"></Setter>
  23.                         </Trigger>
  24.                         <Trigger Property="IsChecked" Value="True">
  25.                                 <Setter Property="ContentTemplate" Value="{StaticResource ArrowToClose}"></Setter>
  26.                         </Trigger>
  27.                 </Style.Triggers>
  28.         </Style>
  29. </ResourceDictionary>
  30.  
Обратим внимание на два обстоятельства:
1. В Visual Studio строка ссылки на файл ресурсов Source="TSResources.xaml" воспринимается ошибкой. Мы выбрали Expression Blend - здесь есть удивительная особенность. После создания файла ресурсов перейдя во вкладку ресурсов справа, "залинковать" ресурс, например, к окну приложения. В частности, следующая часть кода вставлена автоматически Expression Blend.



Затронутый вопрос указания ссылки на файл в XAML, да и шире, вопрос подключения, скажем, внешнего класса (класса из проекта библиотеки в другой сборке) в область видимости файла XAML - довольно каверзная вещь. Например, опытным путем замечено, что файл XAML может не видеть класс "сторонней" библиотеки, хотя внешне все сделано правильно. Часто оказывается достаточным просто перекомпилировать решение при выставленной опции Any CPU (Build -> Configuration Manager). Удивительно, но факт довольно неприятный, особенно когда часами тщетно пытаешься найти причину ошибки.
Код: XML
  1.         <Window.Resources>
  2.                 <ResourceDictionary>
  3.                         <ResourceDictionary.MergedDictionaries>
  4.                                 <ResourceDictionary Source="TSResources.xaml"/>
  5.                         </ResourceDictionary.MergedDictionaries>
  6.                 </ResourceDictionary>
  7.         </Window.Resources>
  8.  
2. Строки вида "F1 M 0,0L 82.377,0L 82.377,122.717L 0,122.717L 0,0" указывают на язык (скрипт) плоской графики, применяемый дополнительно внутри XAMl. Ничто не мешает им пользоваться и непосредственно в коде.

« Последнее редактирование: Январь 21, 2013, 01:35:36 am от Sergey »