среда, 25 марта 2009 г.

Behaviors + Blend = WOW!

Что такое Behavior?


На Mix 09 парни из Microsfot показывали 3-й Expression Blend, который уже можно скачать и установить (ставится на ура рядом со вторым блендом). В новом бленде появилась возможность создавать Behaviors - поведения. Сложно сказать конкретно, что такое "поведение", т.к. оно может быть чем угодно :). Поведения наделяют объект каким-либо свойством. Например, на презентации длиною в 18 минут, Pete Blois дает возможность кнопкам:
  • Соответствовать законам физики: при запуске приложения кнопки начинают падать.
  • Обладать свойством перетаскивабельности: можно потянуть кнопку мышкой. А т.к. кнопка еще и действует по законам физики, вы получите некоторое последействие, когда отпустите мышку. Кнопка поедет чуточку дальше :).
  • Обладать магнетизмом: кнопка начинает притягивать другие объекты :).
Поведения работают как в Silverlight 3.0, так и в WPF. В Preview версии Blend'a нет стандартных поведений:
но, на сайте Microsoft Expression Community Gallery, уже можно скачать те поведения, что использовал Pete в своей презентации :).

Как создать свое поведение?

Здесь приводится алгоритм создания своего поведения на примере DragBehavior'a, наделяющего объект свойством перетягивабельности :).
1. Для начала стоит поставить третий бленд :).
2. Создаем новый Silverlight Project (с равным успехом, можно создавать WPF проект, но пример мы сделаем на Silverlight'e).
3. В References нашего Silverlight приложения добавляем сборку "Microsoft.Expression.Interactivity.dll" (по умолчанию, она находится в папке "C:\Program Files\Microsoft Expression\Blend 3 Preview\Libraries") :
4. Теперь нам нужно определить новый класс поведения. Поскольку я ленивый, сделаю это прямо в файле с Code behind'ом для моего Entry Point'a в приложение. После редактирования, он выглядит так:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Microsoft.Expression.Interactivity;

namespace SilverlightApplication1
{
 public partial class MainControl : UserControl
 {
  public MainControl()
  {
   // Required to initialize variables
   InitializeComponent();
  }
 }

 public class DragBehavior : Behavior<UIElement>
 {
  private bool _isDragging = false;
  private Point _prevPoint;

  protected override void OnAttached()
  {
   AssociatedObject.MouseLeftButtonDown += AssociatedObject_MouseLeftButtonDown;
   AssociatedObject.MouseMove += AssociatedObject_MouseMove;
   AssociatedObject.MouseLeftButtonUp += AssociatedObject_MouseLeftButtonUp;
  }

  void AssociatedObject_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
  {
   _isDragging = false;
   AssociatedObject.ReleaseMouseCapture();
  }

  void AssociatedObject_MouseMove(object sender, MouseEventArgs e)
  {
   if (!_isDragging)
   {
    return;
   }

   var currentPoint = e.GetPosition(null);
   var left = Canvas.GetLeft(AssociatedObject) +
              currentPoint.X - _prevPoint.X;
   var top = Canvas.GetTop(AssociatedObject) +
             currentPoint.Y - _prevPoint.Y;

   Canvas.SetLeft(AssociatedObject, left);
   Canvas.SetTop(AssociatedObject, top);

   _prevPoint = currentPoint;
  }

  void AssociatedObject_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
  {
   _isDragging = true;
   _prevPoint = e.GetPosition(null);

   AssociatedObject.CaptureMouse();
  }
 }
}
Как видите, новое поведение наследуется от Generic-класса "Behavior". В качестве параметра шаблона мы передаем UIElement, именно к такого типа элементам применимо наше поведение. Единственное ограничение на параметр шаблона: он обязательно должен быть DependencyObject'ом (Почему? - Читайте в следующем посте)
Мы также перекрыли вызов метода "OnAttached()", что произойдет, когда наше поведение будет присоединено к UIElement'у. Сам UIElement доступен через свойство "AssociatedObject". Имея в распоряжении полный доступ к элементу, мы подписываемся на его события мышки, и при зажатой левой кнопке меняем координаты Canvas.Left, Canvas.Top. Конечно, это накладывает ограничения: чтобы пример заработал, нужно положить UIElement в Canvas.
5. Скомпилируем проект, и пойдем в Asset Library. На вкладке Behaviors мы найдем наше поведение:
6. Теперь, имея следующую разметку нашего Root Visual'a:
<UserControl
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 x:Class="SilverlightApplication1.MainControl"
 Width="640" Height="480">

 <Grid x:Name="LayoutRoot" Background="White">
  <Canvas>
   <Rectangle Fill="Green" Width="40" Height="40"/>
  </Canvas>
 </Grid>
</UserControl>
Мы можем перетащить DragBehavior на Rectangle. После этого, наш Rectangle получает... присоединенное DependencyProperty: Interaction.Behaviors:
<Rectangle Fill="Green" Width="40" Height="40">
 <i:Interaction.Behaviors>
  <local:DragBehavior/>
 </i:Interaction.Behaviors>
</Rectangle>
7. Запустив приложение, мы сможем возькать мышкой прямоугольник.

Как работают поведения?

Об этом читайте в следующем посте :).

Комментариев нет:

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