Silverlight 1.1 - Animasyon ve Mouse İşlemlerine Giriş

0 dakikada yazıldı

6052 defa okundu

Düzenle

Nerden çıktı Silverlight 1.1? Aslına bakarsanız Silverlight 1.1 üzerine
uzun bir süre makale yazmayı düşünmüyordum. Bunun nedeni daha
Silverlight 1.1'in Alpha aşamasında olması. Yani şu anki yazılım,
teknoloji ile yayınlanacak Silverlight 1.1 arasında dağlar kadar farklar
olabilir (hatta olacaktır). O nedenle hali hazırda elimizdeki değerli
zamanımızı ağırlıklı olarak Silverlight 1.0 ile tüketmek özellikle
kurumsal projeler için çok daha mantıklı. Diğer yandan Silverlight 1.1
ile geliştirdiğimiz bir uygulamayı çalıştırmaları için istemcilere yine
Alpha aşamasında Silverlight 1.1 Plug-In'ini yüklemelerini de
isteyemeyiz. Gerçeği söylemek gerekirse ben orijinal makineme hiçbir
zaman Beta ve Alpha yazılım kurmam, bu tarz denemeler için sanal makine
kullanırım.

Silverlight 1.1 ile 1.0 sürümü arasındaki en büyük fark programlama
kısmında. Silverlight 1.0'da JavaScript ile istemci taraflı programlama
yapabiliyorken Silverlight 1.1 sürümünde .NET dillerini de kullanma
şansımız var. Yazdığımız kod bir DLL'e çevrilerek yine istemci tarafında
Silverlight 1.1 Plug-In ile çalıştırılıyor. Tabi bu noktada tüm .NET
Framework Silverlight 1.1'e aktarılmış durumda değil. Klasik .NET
Framework 30MB gibi bir boyuta sahipken Silverlight 1.1 Plug-In sadece
3MB. Yani özetle .NET Framework'ün bir kısmı aktarılmış durumda, tamamı
değil.

Farkındaysanız hala neden bu makaleyi yazdığımı açıklamadım :) Blogumu
takip eden dostlarım tarafından bana bir çok soru maili geliyor. Bu
soruların bazılarını cevaplarken "Aslından bunu bir makale haline
getirsem herkes faydalanır
" diyerek anından bir blogpost'a çeviriyorum.
İşte bu makale de böyle bir makale :) Aslında bana gelen maillerden
birince cevap olarak yazılması gereken bir çözüm, ama ben buradan
paylaşarak herkesin okumasına olanak tanımak istiyorum. Arkadaşımız
çözümü C# olarak istemiş, o nedenle bu makaleye özgü olarak C#
kullanacağım. Ama lütfen bu bir gelenek haline gelmesin :) arkadaşlar
.NET geliştiriciler olarak hem C# hem VB kodunu okumayı öğrenmekte
fayda var. Özellikle VB kodunu okumak zaten kolay :) Böylece bana da C#
yazdırmış olmazsınız :) Haz etmediğim açıkça ortada sanırım ;)

Son olarak sorulara geçmeden önce kullandığım geliştirme ortamından da
bahsetmek istiyorum. Örnekleri yaparken Visual Studio 2008 Beta 2
Professional
Edition
ve
Expression Blend 2 September
Preview

kullandım. Sistemimde Plug-In olarak Silverlight 1.1 Alpha September
Refresh

yüklüydü.

Gelen sorulara bakalım :)

Silverlight 1.1 tarafında animasyonlara .NET kodu ile nasıl müdahale
ederiz?

Bunun için ilk olarak bir animasyon hazırlamamız gerekiyor. Aşağıdaki
şekilde bir animasyonu Silverlight sayfamızda Resource olarak
tanımlayalım.

<Canvas

        xmlns="http://schemas.microsoft.com/client/2007"

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

        x:Name="parentCanvas"

        Loaded="Page_Loaded"

        x:Class="SilverlightProject14.Page;assembly=ClientBin/SilverlightProject14.dll"

        Width="640"

        Height="480"

        Background="White"

        >

 

  <Canvas.Resources>

    <Storyboard
x:Name="Timeline1">

      <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="ellipse"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">

        <SplineDoubleKeyFrame KeyTime="00:00:00"
Value="0"/>

        <SplineDoubleKeyFrame KeyTime="00:00:01"
Value="209"/>

      </DoubleAnimationUsingKeyFrames>

      <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="ellipse"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">

        <SplineDoubleKeyFrame KeyTime="00:00:00"
Value="0"/>

        <SplineDoubleKeyFrame KeyTime="00:00:01"
Value="29"/>

      </DoubleAnimationUsingKeyFrames>

    </Storyboard>

  </Canvas.Resources>

 

  <Ellipse
Width="123" Height="119" Fill="#FFFF0000"
Stroke="#FF000000"
Canvas.Left="71" Canvas.Top="116" x:Name="ellipse"
RenderTransformOrigin="0.5,0.5">

    <Ellipse.RenderTransform>

      <TransformGroup>

        <ScaleTransform
ScaleX="1" ScaleY="1"/>

        <SkewTransform
AngleX="0" AngleY="0"/>

        <RotateTransform Angle="0"/>

        <TranslateTransform X="0" Y="0"/>

      </TransformGroup>

    </Ellipse.RenderTransform>

  </Ellipse>

 

</Canvas>

\

Yukarıdaki kod içerisinde basit bir Ellipse nesnesinin ekrandaki
yeri değiştiriliyor. Yarattığımız StoryBoard'un adı Timeline1
şeklinde bırakılmış. Şimdi istediğimiz şey Ellipse'in kendisine
tıklandığında animasyonun başlatılması. Yazacağımız kod tam olarak
aşağıdaki şekilde olacak.

using System;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Ink;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;

 

namespace SilverlightProject16

{

    public partial class Page : Canvas

    {

        public void Page_Loaded(object o, EventArgs e)

        {

            // Required to initialize
variables

            InitializeComponent();

            ellipse.MouseLeftButtonDown += new MouseEventHandler(ellipse_MouseLeftButtonDown);

        }

 

        void
ellipse_MouseLeftButtonDown(object
sender, MouseEventArgs e)

        {

            Timeline1.Begin();

        }

    }

}

\

Gördüğünüz gibi ilk olarak Page.Loaded durumunda sayfamızda yer alan
ellipse nesnesinin MouseLeftButtonDown durumuna bir Handler
bağlıyoruz. Sonrasında da söz konusu handler içerisinde
Timeline1 nesnemizin begin() metodunu çalıştırarak animasyonu
başlatabiliyoruz. Bu kodu eğer VB.NET koduna çevirecek olursak aradaki
tek fark özel olarak Handler tanımlamak yerinde VB.NET'teki
Handles deyimini kullanarak işi halledebiliyor olmamız. VB.NET
kodunu da koymadan edemeyeceğim sanırım :)

Partial Public Class Page

    Inherits Canvas

 

    Public Sub Page_Loaded(ByVal o As
Object, ByVal e As
EventArgs)

        ' Required to initialize
variables

        InitializeComponent()

    End Sub

 

    Private Sub ellipse_MouseLeftButtonDown(ByVal sender As Object,
ByVal e As System.Windows.Input.MouseEventArgs)
Handles ellipse.MouseLeftButtonDown

        Timeline1.Begin()

    End Sub

End Class

\

Mouse ile nesneleri nasıl boyutlandırırz?

Yukarıdaki soruya kıyasla bu biraz ağır bir konu sayılabilir. İlk olarak
sorunun çözümüne dair mantığı kavramamız gerekiyor. Hedefimiz
Silverlight 1.1 içerisinde bir nesnenin büyüklüğünü, yani genişlik ve
yüksekliğini farenin ekrandaki konumuna göre ayarlayabiliyor olmak.
Kullanıcı fareyi ekranda gezdirdikçe farenin konumuna göre objemizi
tekrar boyutlandıracağız. Boyutlandırma işlemini yapabilmek için fare
ile nesneye tıklandığı anda nesnenin yükseklik ve genişliğini bir kenara
not alıp fare sürüklendikçe eski konumu ile yeni konumu arasındaki farkı
nesnenin boyutuna yansıtacağız. Gelin ilk olarak kullanacağımız global
değişkenlerimizi tanımlayalım.

        Boolean Tikli = false;

        Point BaslangicKonum;

        Double BaslangicYukseklik;

        Double BaslangicGenislik;

\

Gördüğünüz gibi toplam dört adet değişkenimiz var. Bunlardan ilki
Tikli adında bir Boolean değişken. Fare ekranda gezdirildikçe
nesnemizi boyutlandıracağımızdan bahsetmiştik. Tabi boyutlandırma
işleminin başlaması için kullanıcının nesneye tıklayıp sürüklemesi
gerekecek. O nedenle nesneye tıklandığında global değişkenimiz
Tikli'yi True yaparak fare sürüklendikçe boyutlandırılma
yapılmasını onaylayacağız. Farenin sol düğmesi bırakıldığında Tikli
değişkenini False yaparak boyutlandırmayı durduracağız. Bunun
haricinde BaslangicKonum değişkenimiz farenin sürüklemenin başındaki
konumuzun hafızada saklayacak, böylece sürüklenen miktarı bularak
nesneye yansıtacağız. Nesnenin başlangıçtaki genişlik ve yüksekliğini de
birer değişkende saklıyor olacağız. Bu değerler üzerine farenin
ekrandaki konum değişikliğini ekleyeceğiz.

            InitializeComponent();

            ellipse.MouseLeftButtonDown += new MouseEventHandler(ellipse_MouseLeftButtonDown);

            ellipse.MouseLeftButtonUp += new MouseEventHandler(ellipse_MouseLeftButtonUp);

            this.MouseLeftButtonUp +=
new MouseEventHandler(ellipse_MouseLeftButtonUp);

            this.MouseMove += new MouseEventHandler(Page_MouseMove);

\

C# için yukarıdaki gibi Event Handler tanımlamalarımızı yapmamız
gerekiyor. İlk örneğimizdeki aynı XAML kodu kullanarak ellipse
nesnemizi boyutlandıracağız. O nedenle ellipse'in
MouseLeftButtonDown ve MouseLeftButtonUp durumlarını kontrol
etmemiz gerekiyor. Ayrıca Silverlight uygulamamızın genelinde de
MouseLeftButtonUP ve MouseMove durumlarını kontrol edeceğiz. Bu
durumlarda neler yapacağımıza birazdan bakacağız.

        void
ellipse_MouseLeftButtonDown(object
sender, MouseEventArgs e)

        {

            Tikli=true;

            BaslangicKonum=e.GetPosition(this);

            BaslangicGenislik=ellipse.Width;

            BaslangicYukseklik = ellipse.Height;

        }

\

ellipse üzerine fare ile tıklandığında ve farenin düğmesi tıklı
duruma geldiğinde yukarıdaki kodumuz çalışacak. Tıklandığı anda hemen
Tikli değişkenimizi True olarak düzenliyoruz. Sonrasında
e.GetPosition(this) diyerek farenin Silverlight animasyonumuzun
neresinde olduğunu global değişkenimize aktarıyoruz. Aynı şekilde
ellipse'in genişlik ve yüksekliğini de değişkenlerimize alıyoruz.

        void
ellipse_MouseLeftButtonUp(object
sender, MouseEventArgs e)

        {

            Tikli = false;   

        }

\

Yukarıda tanımladığımız kodumuzu hem ellipse'in hem de genel olarak
Silverlight uygulamamızın MouseLeftButtonUp durumuna bağladık. Her
iki şekilde de farenin tuşunu kullanıcı bıraktığında Tikli
değişkenimizi False yaparak artık boyutlandırma işleminin
yapılmamasını sağlayacağız. Gelelim boyutlandırma işlemine.

        void Page_MouseMove(object sender, MouseEventArgs e)

        {

            if (Tikli)

            {

                Point SimdikiKonum
= e.GetPosition(this);

                ellipse.Width = Math.Abs(SimdikiKonum.X-BaslangicKonum.X+BaslangicGenislik);

                ellipse.Height  = Math.Abs(SimdikiKonum.Y -
BaslangicKonum.Y + BaslangicYukseklik );

            }

        }

\

Genel olarak tüm Silverlight uygulamamız üzerinde fare sürüklendiği
sürece yukarıdaki kod çalışacak. İlk olarak Tikli değişkenini
kontrol ediyoruz. Eğer fare ile ellipse nesnemize tıklanmışsa ona
uygun boyutlandırma işlemini yapmamız gerekiyor. SimdikiKonum adında
bir değişken tanımlayarak farenin mevcut konumunu alarak hem X hem de Y
yönlerinde farenin başlangıçtaki konumu ile farklarını, üzerine de
nesnemizin başlangıçtaki genişlik ve yüksekliğini koyarak tekrar
genişlik ve yükseklik değerlerine aktarıyoruz. Böylece farenin
sürüklenme miktarı nesnenin genişliğine ve yüksekliğine eklenmiş oluyor.
Tüm bunları yaparken Math.Abs metodu ile hesaplanan değerin mutlak
değerini alarak nesnemizin her zaman görünür boyutlarda olmasını
sağlıyoruz.

Kodumuzun tamamı aşağıdaki şekilde sonlanıyor.

using System;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Ink;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;

 

namespace SilverlightProject16

{

    public partial class Page : Canvas

    {

        Boolean Tikli = false;

        Point BaslangicKonum;

        Double BaslangicYukseklik;

        Double BaslangicGenislik;

 

        public void Page_Loaded(object o, EventArgs e)

        {

            // Required to initialize
variables

            InitializeComponent();

            ellipse.MouseLeftButtonDown += new MouseEventHandler(ellipse_MouseLeftButtonDown);

            ellipse.MouseLeftButtonUp += new MouseEventHandler(ellipse_MouseLeftButtonUp);

            this.MouseLeftButtonUp +=
new MouseEventHandler(ellipse_MouseLeftButtonUp);

            this.MouseMove += new MouseEventHandler(Page_MouseMove);

        }

 

        void Page_MouseMove(object sender, MouseEventArgs e)

        {

            if (Tikli)

            {

                Point SimdikiKonum
= e.GetPosition(this);

                ellipse.Width = Math.Abs(SimdikiKonum.X-BaslangicKonum.X+BaslangicGenislik);

                ellipse.Height  = Math.Abs(SimdikiKonum.Y -
BaslangicKonum.Y + BaslangicYukseklik );

            }

        }

 

        void
ellipse_MouseLeftButtonUp(object
sender, MouseEventArgs e)

        {

            Tikli = false;   

        }

 

        void
ellipse_MouseLeftButtonDown(object
sender, MouseEventArgs e)

        {

            Tikli=true;

            BaslangicKonum=e.GetPosition(this);

            BaslangicGenislik=ellipse.Width;

            BaslangicYukseklik = ellipse.Height;

        }

    }

}

\

Bir de VB.NET tarafına bakalım :)

Partial Public Class Page

    Inherits Canvas

    Dim Tikli As Boolean
= False

    Dim BaslangicKonum As Point

    Dim BaslangicGenislik As Double

    Dim BaslangicYukseklik As Double

 

    Public Sub Page_Loaded(ByVal o As
Object, ByVal e As
EventArgs)

        ' Required to initialize
variables

        InitializeComponent()

    End Sub

 

    Private Sub ellipse_MouseLeftButtonDown(ByVal sender As Object,
ByVal e As MouseEventArgs) Handles ellipse.MouseLeftButtonDown

        Tikli = True

        BaslangicKonum = e.GetPosition(Me)

        BaslangicGenislik = ellipse.Width

        BaslangicYukseklik = ellipse.Height

    End Sub

 

    Private Sub ellipse_MouseLeftButtonUp(ByVal sender As Object,
ByVal e As MouseEventArgs) Handles ellipse.MouseLeftButtonUp

        Tikli = False

    End Sub

 

    Private Sub Page_MouseLeftButtonUp(ByVal sender As Object,
ByVal e As MouseEventArgs) Handles Me.MouseLeftButtonUp

        Tikli = False

    End Sub

 

    Private Sub Page_MouseMove(ByVal sender As Object,
ByVal e As MouseEventArgs) Handles Me.MouseMove

        If Tikli Then

            Dim SimdikiKonum As Point = e.GetPosition(Me)

            ellipse.Height = Math.Abs(SimdikiKonum.Y -
BaslangicKonum.Y + BaslangicYukseklik)

            ellipse.Width = Math.Abs(SimdikiKonum.X - BaslangicKonum.X +
BaslangicGenislik)

        End If

    End Sub

End Class

\

Böylece sorunumuzu çözmüş aldık. Artık ellipse nesnesine tıklanarak
nesne Silverlight animasyonu içerisinde boyutlandırılabilecek.

Silverlight 1.1 ile ilgili gelen sorular şimdilik bu kadar.

Hepinize kolay gelsin.