Makale Özeti

Bu yazımızda Silverlight 3.0 ile beraber gelen Behavior yapısında kullanabileceğimiz kendi Behavior'larımızı yaratmanın yolunu inceleyeceğiz.

Makale

Dün Expression Blend 3 içerisinde Behaviorlara göz attık. Bugün de gelin bir yazılımcı gözü ile nasıl Behavior yaratabiliriz inceleyelim.

Behavior'lar kendi içlerinde ayrı gruplarda incelenebilirler. Bazıları bir event üzerinden tetiklenmesi gerekirken bazıları ise doğal yoldan bağlandıkları nesnelere bir özellik ekleyebiliyorlar. Örneğin GoToStateAction aslında TriggerAction tipinde bir Behavior olarak karşımıza çıkarken FluidMoveBehavior ise tek başına Trigger içermeyen bir Behavior olarak tasarlanmıştır. Bu gibi farklı Behavior tiplerinin programlanması da kısmen tabi ki birbirinden farklı oluyor.

Bu yazımızda inceleyeceğimiz Behavior'lar Trigger içermeyen ve hedef kontrollerine özellik katma amacı güden Behavior'lar olacak.

Nasıl Behavior yazarız?

Behavior'lar System.Windows.Interactivity.dll içerisinde saklı Behavior<T> / Behavior(Of T) sınıfından türeyerek oluşturulular. O nedenle yarattığımız yeni bir Silverlight projesi içerisinde ilk olarak söz konusu DLL'i referans olarak eklemeliyiz. Projenize "solution explorer" içerisinde sağ tuş tıklayarak "add reference" komutunu verdiğiniz System.Windows.Interactivity karşınıza gelecektir. Hemen referans olarak ekleyerek ilerleyebilirsiniz.

Yeni Silverlight projemizde Behavior'ımızı yazmak için yeni bir VB/CS dosyası ekleyerek Behavior sınıfından türeyen yeni bir sınıf yaratıyoruz.

[VB]

Public Class OpacityBehavior

    Inherits Interactivity.Behavior(Of UIElement)

 

 

End Class

[C#]

    public class OpacityBehavior : System.Windows.Interactivity.Behavior<UIElement>

    {

    }

Behavior sınıfından türetirken generics yapısını kullanarak UIElement'i parametre olarak verdiğimizi görebilirsiniz. Bunun nedeni geliştirdiğimiz Behavior'ın tüm UIElement'lere uygulanabilecek olması. Behaviorımız şimdilik örnek olması amacıyla basit bir işlem yapacak ve kendisine verilen herhangi bir kontrolün fare ile üzerine gelinmesi halinde şeffaflığını değiştirecek. Böylece üzerine gelince şeffaf, çıkınca normal gözüken kontroller tasarlamak istersek doğrudan bu geliştirdiğimiz Behavior'ı kullanabileceğiz.

Şeffaflık değişimi için erişmemiz gereken property olan Opacity aslında UIElement'ten türetilmiş tüm kontrollerde bulunduğu için bizim de UIElement'leri hedeflememiz doğru olacaktır.

[VB]

    Private POpacity As Double

    <ComponentModel.Category("Behavior Özellikleri")> _

    Public Property Opacity() As Double

        Get

            Return POpacity

        End Get

        Set(ByVal value As Double)

            POpacity = value

        End Set

    End Property

[C#]

        [System.ComponentModel.Category("Behavior Özellikleri")]

        public double Opacity { get; set; }

Yukarıdaki basit bir şekilde Opacity adında bir Property tanımlıyoruz. Bu property bizim Behavior'ımızın bir propertysi olacak. Böylece kullanıcıların Behavior'ı kullanırken kendisine parametre olarak hedef kontrolün fare ile üzerine gelindiğinde ne kadar şeffaf olmasını istediklerini yazabilecekler. Bu Property Expression Blend içerisinde sağ kolonda gözükecek. Blend içerisinde Properties panelinde bu şekilde Property'lerinizi gruplayabilirsiniz. Property'mize verdiğimiz meta data bunu sağlıyor. Şimdi sıra geldi hedef kontrolü ve onun MouseEnter, MouseLeave eventlarını yakalamaya.

[VB]

    Protected Overrides Sub OnAttached()

        AddHandler AssociatedObject.MouseEnter, AddressOf MouseEnter

        AddHandler AssociatedObject.MouseLeave, AddressOf MouseLeave

        MyBase.OnAttached()

    End Sub

 

    Protected Overrides Sub OnDetaching()

        RemoveHandler AssociatedObject.MouseEnter, AddressOf MouseEnter

        RemoveHandler AssociatedObject.MouseLeave, AddressOf MouseLeave

        MyBase.OnDetaching()

    End Sub

[C#]

       protected override void OnAttached()

        {

            AssociatedObject.MouseEnter += new MouseEventHandler(AssociatedObject_MouseEnter);

            AssociatedObject.MouseLeave += new MouseEventHandler(AssociatedObject_MouseLeave);

            base.OnAttached();

        }

 

        protected override void OnDetaching()

        {

            AssociatedObject.MouseEnter -= new MouseEventHandler(AssociatedObject_MouseEnter);

            AssociatedObject.MouseLeave -= new MouseEventHandler(AssociatedObject_MouseLeave);

            base.OnDetaching();

        }

Yukarıdaki kod grubunda da gördüğünüz üzere BaseClass'tan gelen OnAttached ve OnDetaching metodlarını override ediyoruz. Bu metodlar aslında Behavior nesnemizin yaratıldığı anda çalışan OnAttached ve sahneden kaldırıldığı anda çalışan OnDetaching eventları şeklinde düşünülebilir. Biz de bu durumda OnAttached içerisinde hemen AssociatedObject'e ulaşarak istediğimiz eventları bağlıyoruz. AssociatedObject otomatik olarak bu Behavior'ın içerisine konduğu yani hedeflediği kontrolün bir referansını taşıyor. Aynı şekilde herhangi bir karışıklık olmasın diye OnDetaching'de de event listenerlarımızı kaldırıyoruz.

[VB]

    Public Sub MouseEnter(ByVal sender As Object, ByVal e As System.Windows.Input.MouseEventArgs)

        AssociatedObject.Opacity = POpacity

    End Sub

 

    Public Sub MouseLeave(ByVal sender As Object, ByVal e As System.Windows.Input.MouseEventArgs)

        AssociatedObject.Opacity = 1

    End Sub

[C#]

        void AssociatedObject_MouseLeave(object sender, MouseEventArgs e)

        {

            AssociatedObject.Opacity = 1;

        }

 

        void AssociatedObject_MouseEnter(object sender, MouseEventArgs e)

        {

            AssociatedObject.Opacity = Opacity;

        }

Eh artık sıra geldi MouseEnter ve MouseLeave durumlarında yapılacakları yazmaya. Gördüğünüz gibi daha önce yarattığımız parametremizden gelen değeri hemen duruma göre AssociatedObject'in Opacity özelliğine aktarıyoruz. Burada tabi ki hoş bir animasyon da kullanabilirdik.

Bu behavior'ı nasıl kullanacağız?

Herşeyi kaydettikten sonra projenizi Blend içerisinde açarsanız Asset Library içerisinde Behaviors tabında kendi Behavior'ınızı da görebilirsiniz. Hemen herhangi bir kontrole ataçlayarak sağ tarafta da ayarladığımız özellikleri inceleyebilirsiniz.

Blend içerisinde kendi Behavior'ımız.
Blend içerisinde kendi Behavior'ımız.

Aşağıdaki XAML koduna baktığımızda ise iki farklı XML NameSpace'i görebiliyoruz. Bunlardan biri doğrudan System.Windows.Interactivity'i hedeflerken local adındaki diğeri ise bizim kendi projemizin Assembly'sini hedefliyor. Bu NameSpace'ler üzerinden behavior'ımızı rahatlıkla kullanabiliyoruz.

[XAML]

<UserControl

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

   mc:Ignorable="d"

   xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

   xmlns:local="clr-namespace:SilverlightApplication1"

   x:Class="SilverlightApplication1.MainPage"

   d:DesignWidth="640" d:DesignHeight="480">

  <Grid x:Name="LayoutRoot">

      <Rectangle Fill="Red" Stroke="Black" Margin="154,177,273,163">

          <i:Interaction.Behaviors>

              <local:OpacityBehavior Opacity="0.2"/>

          </i:Interaction.Behaviors>

      </Rectangle>

  </Grid>

</UserControl>

Gördüğünüz gibi Behavior yazmak hiç de zor değil. Yazdığınız her Behavior tasarımcıların işini kolaylaştırmakla kalmıyor aynı anda yazılımcılar olarak sizin iş yükünüzü de azaltıyor.

Hepinize kolay gelsin ;)

Makaleye ait örnek kodlar.