Silverlight 3.0'da ChildWindow nedir? Nasıl kullanılır?

0 dakikada yazıldı

7257 defa okundu

Düzenle

Web uygulamalarında olsun Windows uygulamalarında olsun belki de en sık
başvurduğumzu şey MessageBox'tır :) Sürekli bir yerlerde uyarılar
gösterir ve en basit şekilde kullanıcıya bir mesaj iletmek için
MessageBox yapısını kullanırız. Web ortamında da JavaScript alert
imdadımıza yetişir. Peki ya Silverlight içerisinde?

"Silverlight içinde de MessageBox var!" dediğinizi duyar gibiyim :) ama
MessageBox'ın biraz modası geçmedi mi artık? Şöyle daha güzel şeyler
yapsak? Bir de üstüne yeri geldiğinde sadece bir mesaj değil de belki
Web'deki PopUp'lar tadında farklı işlevsellikler içerebilen ekranlar da
açmak istesek ne yapacağız? Tek tek UserControl'ler hazırlayıp sahnede
uygun gerlerde göstermekle uğraşamayacak kadar basit bir işlevsellikten
bahsediyoruz aslında. Tamam, daha fazla uzatmayacağım...

Karşınızda : "ChildWindow"!

Herhangi bir Silverlight projesine Solution Explorer içerisinde sağ
tıklayarak "Add New Item" menüsüne geçtiğinizde karşınıza gelecek
seçenekler arasına artık "Silverlight Child Window" da eklendi.

Yeni bir nesne tipi : Child Window
Yeni bir nesne tipi : Child Window

Silverlight içerisinde "UserControl" haricinde yapılara pek alışık
değildik :) Silverlight 3.0 ile beraber karşımıza farklı şeyler çıkıyor.
Bunlardan biri de System.Windows.Controls.dll'i altında bulunan
ChildWindow nesnesi. Basit bir şekilde projenize bir ChildWindow
eklediğinizde zaten ChildWindow'un otomatik olarak belirli standart bir
tasarım ile geldiğini de göreceksiniz. Bu tasarım tabi ki Expression
Blend ile açılıp değiştirilebilecek bir tasarım. Kontrolün XAML kısmına
bakarsanız iki tane Button göreceksiniz, söz konusu buttonların Click
durumlarında da arka planda ChildWindow'un DialogResult özelliği set
ediliyor.

[VB]

    Private Sub OKButton_Click(ByVal sender As Object,
ByVal e As RoutedEventArgs) Handles OKButton.Click

        Me.DialogResult = True

    End Sub

 

    Private Sub CancelButton_Click(ByVal sender As Object,
ByVal e As RoutedEventArgs) Handles CancelButton.Click

        Me.DialogResult = False

    End Sub

[C#]

        private void OKButton_Click(object sender, RoutedEventArgs e)

        {

            this.DialogResult = true;

        }

 

        private void CancelButton_Click(object sender, RoutedEventArgs e)

        {

            this.DialogResult = false;

        }

Tahmin edeceğiniz üzere ChildWindow'un kullanımı epey kolay.
ChildWindow'unuzu herhangi bir UserControl'den bir Instance'ını alarak
Show metodu ile çağırabiliyor veya aynı şekilde Close metodu ile
de uzaktan kapatabiliyorsunuz. Örneğin aşağıda gördüğünüz kod herhangi
bir UserControl içerisinde biraz önce yarattığımız ChildWindow'u çağıran
kodun ta kendisi.

[VB]

        Dim Yeni As New
ChildWindow1

        Yeni.Show()

[C#]

            ChildWindow1 Yeni =
new ChildWindow1();

            Yeni.Show();

Sanırım daha basit olamazdı. Tabi söz konusu ChildWindow'u çağırdıktan
sonra kapandığından da haberdar olup hatta kapanmadan önce en son aldığı
DialogResult değerin de elde etmek gerekir. Bunun için ChildWindow'un
Closed event'ını yakalamanız yeterli olacaktır.

[VB]

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

        Dim Yeni As New
ChildWindow1

        AddHandler Yeni.Closed, AddressOf yeni_Closed

        Yeni.Show()

    End Sub

 

    Private Sub yeni_Closed(ByVal sender As Object,
ByVal e As System.EventArgs)

        Dim Sonuc As Boolean
= CType(sender,
ChildWindow1).DialogResult

    End Sub

[C#]

        void MainPage_Loaded(object sender, RoutedEventArgs e)

        {

            ChildWindow1 Yeni =
new ChildWindow1();

            Yeni.Closed += new EventHandler(Yeni_Closed);

            Yeni.Show();

        }

 

        void Yeni_Closed(object sender, EventArgs e)

        {

            Nullable<Boolean> Sonuc = ((ChildWindow1)sender).DialogResult;

        }

ChildWindow'u Show etmeden önce Closed eventını bir
event-listener'a bağlarsanız sonrasında ChildWindow kapatıldığında
rahatlıkla durumdan haberdar olabilirsiniz. Closed event'ı
çalıştırıldığı anda sender olarak gelen objeyi kendi
ChildWindow'umuza cast ederek DialogResult özelliğini alabiliyoruz.
Eğer "Bana sadece Boolean sonuç döndürnek yetmez" diyorsanız aslında
çözüm basit. Kendi tanımladığınız ChildWindow'un arkasında sınıfta yeni
Property'ler tanımlayabilir ve bunları istediğiniz tipte
yaratabilirsiniz. Böylece Closed event'ına gelen sender da
aslında sizin tanımladığınız nesne olacağı için istediğiniz
Property'sine erişebilirsiniz. Eğer ChildWindow kapanmadan önce sizin
tanımladığınız Property'ye bir bilgi aktarırsa bu bilginin rahatlıkla
ana UserControl'e gelebileceği anlamına gelir.

ChildWindow karşınızda.
ChildWindow karşınızda.

Gelin hızlı ve teorik bir örnek yapalım. Hazırlayacağımız yeni
ChildWindow bizden bir Integer parametre alsın. Bu parametreyi aldıktan
sonra zaten ChildWindow kendi içerisinde istediğini yapar. İsterse kendi
içine konabilecek bir TextBlock'a bile yazdırabilir. (Uyarı mesajı
olabilirdi bu parametre) Ama biz farklı birşey yapacağız. ChildWindow'un
OK düğmesine basıldığında kendisine daha önce verilen sayıyıyı ikiyle
çarpıp geri verecek, Cancel düğmesine basılınca ise ikiye bölecek.
Böylece yeni bir ChildWindow yaratırken nasıl parametre geçebileceğimizi
ve söz konusu parametre üzerinde ChildWindow değişiklik yaptıktan sonra
parametreyi nasıl geri alabileceğimizi görmüş oluruz.

[VB]

Partial Public Class ChildWindow1

    Inherits ChildWindow

 

    Public Sub New(ByVal deger As
Integer
)

        InitializeComponent()

**       ** Me.Deger = deger

    End Sub

 

**   ** Private PDeger As Integer

**   ** Public Property Deger() As
Integer

**       ** Get

**           ** Return PDeger

**       ** End Get

**       ** Set(ByVal value As
Integer
)

**            PDeger = value**

**       ** End Set

**   ** End Property

 

    Private Sub OKButton_Click(ByVal sender As Object,
ByVal e As RoutedEventArgs) Handles OKButton.Click

**       ** Me.Deger *= 2

        Me.DialogResult = True

    End Sub

 

    Private Sub CancelButton_Click(ByVal sender As Object,
ByVal e As RoutedEventArgs) Handles CancelButton.Click

**       ** Me.Deger /= 2

        Me.DialogResult = False

    End Sub

 

End Class

[C#]

namespace SilverlightApplication5

{

    public partial class ChildWindow1 : ChildWindow

    {

        public ChildWindow1(int deger)

        {

            InitializeComponent();

**           ** this.Deger =
deger;

        }

 

**       ** public int Deger { get; set; }

 

        private void OKButton_Click(object sender, RoutedEventArgs e)

        {

**           ** this.Deger =
this.Deger * 2;

            this.DialogResult = true;

        }

 

        private void CancelButton_Click(object sender, RoutedEventArgs e)

        {

**           ** this.Deger =
this.Deger / 2;

            this.DialogResult = false;

        }

    }

}

Yukarıda kalın yazılı olarak gördüğünüz yerler bizim eklememiz gereken
satırlar. Hemen ChildWindow'umuzun Constructor'ı ile işe başlayalım.
Artık elimizdeki Constructor bir parametre istiyor. Bu parametre
ChildWindow'a aktarılacak olan veriyi temsil edecek. Bizim örneğimizde
Integer olabilir fakat siz farklı nesne tiplerini ve hatta kendi
tanımladığınız nesne tiplerini de parametre olarak geçebilirsiniz.
Sonrasında söz konusu parametreyle gelen değişkeni elde saklayabilmek
için bir de Property tanımlıyoruz, hatta constructor çalıştığında da
kendisine gelen veriyi Property'e atamasını sağlıyoruz.

Artık verimizi rahat rahat elimize aldığımıza göre Ok ve Cancel
düğmelerinde söz konusu veriyi istediğimiz gibi değiştirebiliriz. Farklı
senaryolarda ChildWindow içerisinde koyduğunuz farklı kontrollerden
gelen verilere göre bu şekilde farklı Property'leri değiştirebilirsiniz.
Peki söz konusu ChildWindow'u çalıştıran UserControl buradaki
Property'ye nasıl ulaşacak? Aslında çok kolay.

[VB]

    Private Sub yeni_Closed(ByVal sender As Object,
ByVal e As System.EventArgs) Handles yeni.Closed

        Dim Sonuc = CType(sender, ChildWindow1).Deger

    End Sub

[C#]

        void Yeni_Closed(object sender, EventArgs e)

        {

            int Sonuc = ((ChildWindow1)sender).Deger;

        }

Gördüğünüz gibi ChildWindow kapandıktan sonra nasıl DialogResult
değerini aldıysak aynı şekilde kendi tanımladığımız Property'lere de
ulaşabiliyoruz. Ne de olsa sender'ı kendi tanımladığımız
ChildWindow1 sınıfına cast ediyoruz. İşte bir ChildWindow'a
parametre gönderip farklı veriler alabilmek bu kadar kolay.

Hmm iyiymiş...

Kesinlikle muhteşem! İster özel Property'ler tanımlayın ister
ChildWindow'un constructor'larını değiştirip farklı bilgiler atayarak
onları göstermesini sağlayın ChildWindow'lar kullanım açısından çok
pratik ve şık. Otomatik olarak kendi kendileri ekranın geri kalanını
yarı şeffaf bir perde ile kapatıp kullanılamaz hale getirmeler ve hoş
bir animasyon ile ekrana gelip gitmeleri gerçekten iş uygulamalarında
genel kullanıma çok uygun. Fakat tabi ki özel durumlarda, kullanıcı
deneyiminin ve tasarımın daha öne çıktığı senaryolarda kesinlikle
ChildWindow'ların özelleştirilmesi gerekiyor.

Aklıma gelmişken :) Ben bir projede ChildWindow'ları sadece Loading
animasyonları göstermek için kullandım. Gerçekten pratik oluyor. Loading
mesajını verirken istediğimiz şey zaten kullanıcının başka birşey
yapamaması. Tabi bu amaçla yaratılan bir ChildWindow'un Close vs gibi
düğmelerinin tasarımdan Blend aracılığı ile kaldırılması gerekiyor. Arka
planda yükleme işlemi bittiğinde siz ChildWindow'un Close metodu ile
pencereyi ekrandan kaldırabiliyorsunuz. Eh pencerenin için de bir de
Indeterminate state'te ProgressBar varsa zaten yeme de yanında yat :)

Hepinize kolay gelsin...