Silverlight 2.0 kontrolleri yaratmanın yolu.

0 dakikada yazıldı

5661 defa okundu

Düzenle

Silverlight 2.0 içerisinde kullandığımız standart kontrollerin yanı sıra
istersek kendi kontrollerimizi de hazırlama şansımız var. Daha önceleri
ister ASP.NET ister Windows uygulamalarından alışık olduğumuz bu
uygulama ile hazırladığınız size özel kontrolleri farklı projelerde
rahatlıkla kullanma şansına sahip olabilirsiniz. Bu yazımızda deneme
amaçlı olarak Silverlight 2.0 ile beraber gelen Button kontrolünü baz
alıp geliştirerek yeni bir kontrol oluşturacağız. Yaratacağımız yeni
TimeOutButton kontrolü kullanıcından bir TimeOut değeri alacak.
Milisaniye cinsinden verilen bu süre sonunda Button kullanılamaz hale
gelecek. Bu esnada Button'un üzerinde sürekli kaç saniye kaldığı da
yazılacak. Kullanıcıların belirli bir sürede bir işlemi tamamlamasını
istiyorsanız bu gibi bir Button işinizi görebilir. Gelin hemen işe
koyulalım.

Çalışma ortamımızı hazırlayalım.

Kontrolümüzü geliştirirken sürekli test etmek isteyeceğiz. O nedenle ilk
olarak sağlıklı bir çalışma ortamı hazırlamamız lazım. Yeni bir
Silverlight projesi yarattığınızda Visual Studio içerisinde Solution
içinde bir ASP.NET ve bir de Silverlight projeniz bulunur. Solution
dosyasına bir proje daha ekleyeceğiz. Solution Explorer içerisinde
solution dosyasına sağ tuş ile tıkladıktan sonra "Add / New Project"
diyerek "Silverlight Class Library" seçeneğini işaretlemeniz yeterli
olacaktır. Böylece yeni kontrolümüzü oluşturmak için kodlarımızı
yazacağımız ortamı geliştirdik.

Solution'ı Compile ettiğimizde Silverlight projemize otomatik olarak bu
kontrol projemizin de eklenmesi gerekiyor. O nedenle hemen Silverlight
projesine sağ tuş ile tıklayarak gelen menüden "Add Reference" komutunu
verin ve karşınıza gelen pencereden de "Projects" tabına geçerek Class
Library projenizi seçin. Böylece artık F5'e bastığınızda her şey
otomatik olarak yapılacaktır ve kontrolünüzü kullanılır şekilde
inceleyebileceksiniz. Tabi testlere geçmeden önce biraz kod yazmamız
gerekiyor ;)

Kontrolümüzü hazırlayalım.

Class Library içerisinde kod dosyamızda düğmemizin adını taşıyan bir
Class bulunuyor. Bu Class'ı biz örneğimizde standart Silverlight Button
kontrolünden inherit edeceğiz. Böylece yeni ve gelişmiş bir Button
yaratırken her şeye sıfırdan başlamayacağız, Silverlight içerisinde
hazır Button kontrolünü alarak üzerine yeni işlevsellikler ekleyeceğiz.

[VB]

Public Class TimeOutButton

    Inherits Button

 

End Class

[C#]

namespace TimeOutBtn

{

    public class TimeOutButton : Button

    {

       

    }

}

Bir sonraki adımda hemen kontrolümüze yeni bir Property tanımlayalım.
Property'miz sayesinde kullanıcıların düğmenin ne kadar süre aktif
kalacağını tanımlayabilecekler.

[VB]

    Private PTimeOut As Integer

    Public Property TimeOut() As Integer

        Get

            Return PTimeOut

        End Get

        Set(ByVal value As Integer)

            PTimeOut = value

        End Set

    End Property

[C#]

        public int TimeOut { get; set;
}

Düğmemiz ilk olarak sayfada gözüktüğünde hemen işlemlere başlamamız
gerekiyor. İlk olarak düğmenin için sayaç bilgisi yazacak yeni bir
kontrol eklememiz şart. Düğmenin Content özelliği duruma göre
doğrudan bir String olabilir veya Content içerisinde farklı Silverlight
nesneleri bulunabilir. Tüm bunları göz önünde bulundurmak zorundayız.

[VB]

        Dim Container As New
StackPanel

        Container.Orientation = Orientation.Vertical

        Container.HorizontalAlignment =
Windows.HorizontalAlignment.Center

        Container.VerticalAlignment = Windows.VerticalAlignment.Center

 

        If Me.Content.GetType() Is System.Type.GetType("System.String") Then

            Dim TextBl As New
TextBlock

            TextBl.Text = Me.Content

            Container.Children.Add(TextBl)

        Else

            Container.Children.Add(Me.Content)

        End If

        Container.Children.Add(MyBox)

        Me.Content = Container

[C#]

            StackPanel Container =
new StackPanel();

            Container.Orientation = Orientation.Vertical;

            Container.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;

            Container.VerticalAlignment = System.Windows.VerticalAlignment.Center;

 

            if (object.ReferenceEquals(this.Content.GetType(), System.Type.GetType("System.String"))) {

                TextBlock TextBl =
new TextBlock();

                TextBl.Text = this.Content.ToString();

                Container.Children.Add(TextBl);

            }

            else {

                Container.Children.Add(this.Content as UIElement);

            }

            Container.Children.Add(MyBox);

            this.Content = Container;

Kodumuz içerisinde ilk olarak bir StackPanel yaratıyoruz. StackPanel'in
özelliklerini ayarladıktan sonra hemen düğmemize atanmış Content'i
kontrol ediyoruz. Amacımız Content içerisinde her ne varsa hepsini
StackPanel içine eklemek. Sonrasında bizim kalan saniye miktarını
göstereceğimiz TextBlock'u da yine StackPanel içerisine ekleyerek
StackPanel'i de düğmenin Content'i yapacağız. Böylece bu TimeOutButton
kontrolünü kullananlar düğmenin Content'ine ne koyarlarsa koysunlar
kalan saniye miktarı sürekli bu Content'in içerisinde gösterilecek.

Eğer düğmeye atanmış Content String tipindeyse bu String'i alıp yeni bir
TextBlock yaratarak içerisine yerleştiriyoruz. TextBlock'umuzu da
StackPanel içine koyuyoruz. Eğer Content String değilse demek ki
kullanıcı düğmenin Content'ine bir Silverlight nesnesi koymuş. Bu
durumda söz konusu nesneyi alıp doğrudan StackPanel içine koyabiliriz.
Son olarak kodumuzda gözükmeyen fakat uygulamamızda global bir değişken
olarak yarattığımız MyBox adındaki TextBlock'u da StackPanel'e ekliyoruz
ve StackPanel'i de düğmenin Content'i yapıyoruz. MyBox kontrolünü global
yaratmamızın nedeni ileriki adımlarda MyBox'ın içeriğine sürekli kalan
saniye miktarını yazdıracak olmamız.

[VB]

    Dim MyBox As New
TextBlock

    WithEvents Timer As New
System.Windows.Threading.DispatcherTimer

[C#]

        TextBlock MyBox = new TextBlock();

        System.Windows.Threading.DispatcherTimer Timer = new System.Windows.Threading.DispatcherTimer();

Global değişkenimiz arasında bir de DispatcherTimer bulunuyor. Bu
Timer ile kalan saniye miktarını sürekli hesaplayıp kontrol ederek
düğmenin içine yazdıracağız.

[VB]

    Private Sub Timer_Tick(ByVal sender As Object,
ByVal e As System.EventArgs) Handles Timer.Tick

        If PTimeOut <= 0 Then

            Timer.Stop()

            MyBox.Visibility = Windows.Visibility.Collapsed

            Me.IsEnabled = False

        Else

            PTimeOut -= 1000

            MyBox.Text = (PTimeOut / 1000).ToString  + " saniye kaldı."

        End If

    End Sub

[C#]

        private void Timer_Tick(object sender, System.EventArgs e)

        {

            if (TimeOut <= 0)

            {

                Timer.Stop();

                MyBox.Visibility = System.Windows.Visibility.Collapsed;

                this.IsEnabled = false;

            }

            else {

                TimeOut -= 1000;

                MyBox.Text = (TimeOut / 1000).ToString() + " saniye kaldı.";

            }

        }

Kodumuzda kalan süreyi PTimeOut adındaki private değişkenimizde
saklayacağız. Eğer kalan süre sıfırın altında ise hemen Timer'ımızı
durduruyor ve kalan süreyi gösteren TextBlock'umuz olan MyBox'ı sahneden
kaldırıp düğmeyi de pasif hale getiriyoruz. Kalan süre sıfırdan büyük
olduğu sürece MyBox TextBlock içerisine gerekli uyarıyı yazdırıp
kalan süreyi Timer'ın Intervali kadar azaltıyoruz.

Expression Blend içerisinde hazırladığımız yeni kontrol.
Expression Blend içerisinde hazırladığımız yeni kontrol

Artık kontrolümüz hazır. Projemizi Blend ile açtığımızda Asset Library
içerisinde Custom Controls tabında kontrolümüzü görebiliyoruz. Sahneye
bir TimeOutButton ekleyip TimeOut özelliğini de ayarladıktan sonra
kontrolümüzü kullanabiliriz.

<UserControl
x
:Class="SilverlightApplication47.Page"

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

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

   Width="400"
Height
="300" xmlns:TimeOutBtn="clr-namespace:TimeOutBtn;assembly=TimeOutBtn">

    <Grid
x
:Name="LayoutRoot"
Background
="White">

          <TimeOutBtn:TimeOutButton TimeOut="5000"
Height
="72" HorizontalAlignment="Left"
Margin
="56,48,0,0" VerticalAlignment="Top"
Width
="128" Content="TimeOutButton"/>

    </Grid>

</UserControl>

Hepinize kolay gelsin. Uygulamanın tam kodunu aşağıda
inceleyebilirsiniz.

[VB]

Public Class TimeOutButton

    Inherits Button

 

    Private PTimeOut As Integer

    Public Property TimeOut() As Integer

        Get

            Return PTimeOut

        End Get

        Set(ByVal value As Integer)

            PTimeOut = value

        End Set

    End Property

 

    Dim MyBox As New
TextBlock

    WithEvents Timer As New
System.Windows.Threading.DispatcherTimer

 

    Private Sub TimeOutButton_Loaded(ByVal sender As Object,
ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded

        Dim Container As New
StackPanel

        Container.Orientation = Orientation.Vertical

        Container.HorizontalAlignment =
Windows.HorizontalAlignment.Center

        Container.VerticalAlignment = Windows.VerticalAlignment.Center

 

        If Me.Content.GetType() Is System.Type.GetType("System.String") Then

            Dim TextBl As New
TextBlock

            TextBl.Text = Me.Content

            Container.Children.Add(TextBl)

        Else

            Container.Children.Add(Me.Content)

        End If

        Container.Children.Add(MyBox)

        Me.Content = Container

        Timer.Interval = New
TimeSpan(0, 0, 1)

        Timer.Start()

    End Sub

 

    Private Sub Timer_Tick(ByVal sender As Object,
ByVal e As System.EventArgs) Handles Timer.Tick

        If PTimeOut <= 0 Then

            Timer.Stop()

            MyBox.Visibility = Windows.Visibility.Collapsed

            Me.IsEnabled = False

        Else

            PTimeOut -= 1000

            MyBox.Text = (PTimeOut / 1000).ToString  + " saniye kaldı."

        End If

    End Sub

End Class

[C#]

using System;

using System.Net;

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 TimeOutBtn

{

    public class TimeOutButton : Button

    {

        public int TimeOut { get; set;
}

 

        TextBlock MyBox = new TextBlock();

        System.Windows.Threading.DispatcherTimer Timer = new System.Windows.Threading.DispatcherTimer();

 

        public TimeOutButton()

        {

            this.Loaded += new RoutedEventHandler(TimeOutButton_Loaded);

            Timer.Tick += new EventHandler(Timer_Tick);

        }

 

        private void TimeOutButton_Loaded(object sender, System.Windows.RoutedEventArgs e)

        {

            StackPanel Container =
new StackPanel();

            Container.Orientation = Orientation.Vertical;

            Container.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;

            Container.VerticalAlignment = System.Windows.VerticalAlignment.Center;

 

            if (object.ReferenceEquals(this.Content.GetType(), System.Type.GetType("System.String"))) {

                TextBlock TextBl =
new TextBlock();

                TextBl.Text = this.Content.ToString();

                Container.Children.Add(TextBl);

            }

            else {

                Container.Children.Add(this.Content as UIElement);

            }

            Container.Children.Add(MyBox);

            this.Content = Container;

            Timer.Interval = new TimeSpan(0, 0, 1);

            Timer.Start();

        }

        private void Timer_Tick(object sender, System.EventArgs e)

        {

            if (TimeOut <= 0)

            {

                Timer.Stop();

                MyBox.Visibility = System.Windows.Visibility.Collapsed;

                this.IsEnabled = false;

            }

            else {

                TimeOut -= 1000;

                MyBox.Text = (TimeOut / 1000).ToString() + " saniye kaldı.";

            }

        }

    }

}