четверг, 28 мая 2009 г.

Шаблоны в WPF

В основе идеи шаблонов лежит концепция отделения функциональности от внешнего вида.
Посмотрите на вот этот рисунок:

Как видно на кнопке размещается CheckBox, картинка, набор RadioButton и даже еще одна кнопка! И все это, как не странно, работает. Достигается это за счет того, что основная масса компонентов имеет свойство Content, в рамках которого мы можем создавать практически любое наполнение. Основной недостаток, мы не можем переопределить саму базовую кнопку. Например, сделать ее треугольной или круглой, хотя цвет, размер и много другое изменить достаточно легко.
Для изменения всего способа отображения и используются шаблоны.
В WPF существует несколько видов шаблонов:
1. ControlTemplate - позволяет задавать шаблон для любого визуального компонента.
2. ItemsPanelTemplate - позволяет задавать шаблон компоновки для контейнеров.
3. DataTemplate - задает шаблоны отображения данных.
4. HierarchicalDataTemplate - задает шаблоны древовидных структур.
Рассмотрим самый простой случай ControlTemplate:
  1.   <Window.Resources>
  2.     <Style TargetType="{x:Type Button}">
  3.       <Setter Property="Background" Value="Black" />
  4.       <Setter Property="Height" Value="40" />
  5.       <Setter Property="Foreground" Value="White" />
  6.       <Setter Property="Margin" Value="3" />
  7.       <Setter Property="Template">
  8.         <Setter.Value>
  9.           <ControlTemplate TargetType="{x:Type Button}">
  10.             <Grid>
  11.               <Rectangle Name="GelBackground" RadiusX="9" RadiusY="9" Fill="Black">                
  12.               </Rectangle>
  13.               <Rectangle Name="GelShine" Margin="2,2,2,0" VerticalAlignment="Top" RadiusX="6" RadiusY="6" Height="15px">
  14.                 <Rectangle.Fill>
  15.                   <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
  16.                     <GradientStop Offset="0" Color="#ccffffff" />
  17.                     <GradientStop Offset="1" Color="Transparent" />
  18.                   </LinearGradientBrush>
  19.                 </Rectangle.Fill>
  20.               </Rectangle>
  21.               <ContentPresenter Name="GelButtonContent" VerticalAlignment="Center" HorizontalAlignment="Center" Content="{TemplateBinding Content}" />
  22.             </Grid>
  23.             <ControlTemplate.Triggers>
  24.               <Trigger Property="IsMouseOver" Value="True">
  25.                 <Setter Property="Rectangle.Fill" TargetName="GelBackground">
  26.                   <Setter.Value>
  27.                     <RadialGradientBrush>
  28.                       <GradientStop Offset="0" Color="Lime" />
  29.                       <GradientStop Offset="1" Color="DarkGreen" />
  30.                     </RadialGradientBrush>
  31.                   </Setter.Value>
  32.                 </Setter>
  33.                 <Setter Property="Foreground" Value="Black" />
  34.               </Trigger>
  35.               <Trigger Property="IsPressed" Value="True">
  36.                 <Setter Property="Rectangle.Fill" TargetName="GelBackground">
  37.                   <Setter.Value>
  38.                     <RadialGradientBrush>
  39.                       <GradientStop Offset="0" Color="#ffcc00" />
  40.                       <GradientStop Offset="1" Color="#cc9900" />
  41.                     </RadialGradientBrush>
  42.                   </Setter.Value>
  43.                 </Setter>
  44.               </Trigger>
  45.             </ControlTemplate.Triggers>
  46.           </ControlTemplate>
  47.         </Setter.Value>
  48.       </Setter>
  49.     </Style>
  50.   </Window.Resources>
  51.   <Grid>
  52.     <Button Width="124">Кнопка с шаблоном</Button>
  53.   </Grid>
* This source code was highlighted with Source Code Highlighter.


Как видно мы задаем новый стиль (строка 2), который переопределяет свойство Template - как раз тот самый шаблон (строка 7 и далее). Все остальное достаточно понятно, кроме наверно строки 17 где цвет задается не как конкретный цвет (напрмер - Red), а как переход к цвету подложки - Transparent. И конечно строка 21 в которой мы задаем, что в нашем шаблоне кнопки в качестве контента должно быть то, что помещено в контент кнопки к которой применен шаблон. В строках 24 и 25 задаются тригеры для изменения цвета кнопки при наведении мышки и при нажатии.
Вот так все это выглядит в обычном режиме, при наведении мышки и нажатии.

Кстати, попробуйте сделать круглую кнопку ;)

2 комментария:

  1. я сделал себе круглую, залил её lineargradientbrush в двух тонах

    сделал на неё такую же границу, только тона поменял. и вышло очень даже красиво )

    спасибо, очень помогла ваша тема )

    ОтветитьУдалить
  2. Вау, кто то начал читать мой блог )))
    Спасибо за отзыв. Появился стимул еще написать пару постов )

    ОтветитьУдалить