Expression Blend ile Databinding

0 dakikada yazıldı

11315 defa okundu

Düzenle

İster Silverlight tarafında olsun ister WPF teknolojinin ve araçların
sürekli bahsedilen en önemli özelliklerinden biri tasarımcı ile
yazılımcı arasındaki ilişkiyi düzenlediği yönünde. Tabi ki eskisine
kıyasla çok sayıda artı özellik bu iki profil arasındaki "kavgaların"
azalmasını sağlıyor fakat diğer yandan özellikle yazılımcının da
Expression Blend uyumlu binding yapılabilir nesnelerini tanımlayabiliyor
olması çok önemli. Tabi aynı derecede bir tasarımcının da Blend
içerisinden yola çıkarak programcının arka planda kendisine sağladığı
CLR nesnelerine ulaşabilmesi şart.

Tüm bu senaryo ile ilgili ufak bir örnek yapacağımız bu yazımızda ilk
olarak bir programcı olarak tasarımcının uygulama tasarımında istediği
gibi işlevsellikleri ayarlayabileceği ve binding'leri set ederek hangi
datanın nerede gözükeceğine karar verebileceği bir altyapı
oluşturacağız. Sonrasonda tasarımcı profili ile Expression Blend'e
geçerek arka tarafta programcının hazırlamış olduğu nesneleri alıp
uygulama arayüzünde istediğimiz yerlere yerleştireceğiz.

Visual Studio tarafından başlayalım!

Varsayalım ki elinizde bir Insan listesi var ve bunu bir şekilde
tasarımcının ellerine aktarmak istiyorsunuz. Sizin bir programcı olarak
yapmanız gereken bu listeyi bir veri kaynağından alıp (bu ister SQL
ister başka bir kaynak olabilir) Expression Blend tarafında
kullanılabilir hale getirmek. Yani verinizin User Interface tarafında
kullanılabilmesini sağlamanız gerekiyor. İlk olarak gelin basit bir
şekilde Insan nesnemizi tanımlayalım.

[VB]

Public Class Insan

 

    Private _Soyadi As String

    Public Property Soyadi() As String

        Get

            Return _Soyadi

        End Get

        Set(ByVal value As String)

            _Soyadi = value

        End Set

    End Property

 

 

    Private _Adi As String

    Public Property Adi() As String

        Get

            Return _Adi

        End Get

        Set(ByVal value As String)

            _Adi = value

        End Set

    End Property

 

End Class

Gördüğünüz gibi nesnemizin şimdilik iki basit özelliği var. Amacımız bu
nesneden birden çok sayıda yaratıp bir liste olarak tasarımcıya
aktarmak. Bunun için ayrı bir sınıf tanımlamamız uygun olur. Söz konusu
sınıf içerisinde de ObservableCollection dönecek bir metod yer
alacak.

[VB]

Public Class AllData

 

    Private _All As New
System.Collections.ObjectModel.ObservableCollection(Of Insan)

    Public Property All() As
System.Collections.ObjectModel.ObservableCollection(Of Insan)

        Get

            Return _All

        End Get

        Set(ByVal value As
System.Collections.ObjectModel.ObservableCollection(Of Insan))

            _All = value

        End Set

    End Property

 

    Sub New()

        _All.Add(New Insan() With {.Adi = "1asdasd", .Soyadi = "2222"})

        _All.Add(New Insan() With {.Adi = "2asdasd", .Soyadi = "4222"})

        _All.Add(New Insan() With {.Adi = "3asdasd", .Soyadi = "5222"})

        _All.Add(New Insan() With {.Adi = "4asdasd", .Soyadi = "6222"})

    End Sub

 

End Class

AllData adındaki bu sınıfın içerisinde All adında da bir
Property var. Bu property geriye bir ObservableCollection
döndürüyor. Bildiğiniz üzere ObservableCollection'lar TwoWay
binding destekleyen collection nesneleridir. Yani görsel arayüzdeki
değer değişiklikleri de otomatik olarak arka plandaki nesneye yansır.
Expression Blend'de bu nesne bind edildiğinde Blend nesneyi çağırmadan
önce bir Instance yani kopyasını alacaktır. İşte tam da bu kopyayı
yaratırken sınıfımızın constructor'ında datamızı
ObservableCollection'ımıza ekleyebiliriz. Kod yönetimi açısından tüm
bu kodları harici bir VB veya C# dosyasında yazmanızda fayda var.

İşimiz bu kadar artık bu veriyi gösterme işi tasarımcının işi.
Expression Blend tarafına geçerek geri kalanı bir tasarımcı profili ile
yapalım.

Expression Blend tarafına geçiyoruz!

Aynı projeyi Expression Blend ile açtıktan sonra sağ barda "Data" tabını
bulabilirsiniz. Data tabında "Add Live Data Source" komutunu verdikten
sonra "Define New Object Data Source" diyebilirsiniz.

Expression Blend içerisinde Data Source'umuzu tanımlıyoruz.
Expression Blend içerisinde Data Source'umuzu tanımlıyoruz.

Karşınızda çıkacak ekranda AllData adındaki sınıfımızı seçmeniz yeni
DataSource'u yaratmanız için yeterli olacaktır. Artık sıra geldi bu
DataSource içerisinde hangi Property'yi nasıl kullanacağınıza.

Nesnelerimiz Expression Blend tarafından algılandı.
Nesnelerimiz Expression Blend tarafından algılandı.

Artık Data tabındaki veri kaynağı ile ilgili tüm detayları görebiliriz.
Tasarımcı olarak Data tabından veriyi sahneye koymak için birkaç yolumuz
var. Bunlardan ilki liste görünüşünü kullanmak. Şu an yukarıdaki ekran
görüntüsünde List Mode gözüküyor. Bu durumda
ObservableCollection'ı alıp sahneye bıraktığınızda otomatik olarak
bir ListBox yaratılacak ve veri ListBox'a bağlanacaktır.

Sürükle, bırak! Ve karşında ListBox!
Sürükle, bırak! Ve karşında ListBox!

Artık bu ListBox'ın ItemTemplate'inin vs tasarımını değiştirmek tabi ki
makalemizin sınırları dışında. Fakat unutmamak gerek ki artık canlı
veriye bağlı ve tamamiyle tasarımı özelleştirilebilir bir ListBox
tasarımcımızın ellerinde. Ayrıca tek seçenek ListBox da değil. Eğer
sahnede bir Grid veya başka bir kontrol olsaydı doğrudan Collection'ı
onun üzerine sürükleyip bırakarak da Data Binding işlemi rahatlıkla
yapılabilirdi.

Details Mode karşınızda.
Details Mode karşınızda.

List Mode'un yanı sıra Blend içerisinde kullanabileceğimiz bir diğer
Data modu da Details Mode olarak karşımıza çıkıyor. Bu moddayken veri
kaynağından nesneleri ancak Property'ler olarak sürükleyip
bırakabilirsiniz çünkü artık amacınız bir liste göstermek değil. Artık
amacımız nesnelerin detaylarınız göstermek. Tek tek her Property'yi
sahnedek ayrı nesnelere Bind edebileceğiniz gibi nesnelerin
yaratılmasını Blend'e de bırakabilirsiniz. Örneğin gelin hem Adi hem de
Soyadi Property'lerini seçerek sahneye sürükleyip bırakalım.

Details Mode ile otomatik detay görünümü yaratabilirsiniz.
Details Mode ile otomatik detay görünümü yaratabilirsiniz.

Gördüğünüz gibi sürükle bırak sonrasında otomatik olarak bir Grid
yaratılarak içerisinde hem Property isimlerini taşıyan hem de
değerleri taşıyan birer TextBlock yerleştirildi. İşin en güzel
tarafı binding işlemini aynı nesne kopyasına yaptığımız için ListBox
içerisinde hangi nesne seçilirse onun detaylarının bu Grid içerisinde
gösterilecek olması. Yani tüm işlevsellik tamamlanmış durumda!

Arka planda Blend neler yaptı?

Blend aslında basit bir şekilde Binding mekanizmalarının tasarımcılar
tarafında rahatlıkla kullanılabilmesini sağlıyor. Maalesef şu an için bu
mekanizmaları yazılımcılar olarak bizim elle yazmaktan başka şansımız
ki. Visual Studio 2010 ile bu durumda toparlanacak ve bizler de tüm bu
ayarları yapabileceğimiz menülere sahip olacağız.

XAML tarafına bir göz atacak olursak dikkatimizi çeken birkaç nokta
olabilir.

[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:local="clr-namespace:SilverlightApplication2"
xmlns:dataFormToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit"
x:Class="SilverlightApplication2.MainPage"

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

    <UserControl.Resources>

        <local:AllData
x
:Key="AllDataDataSource" d:IsDataSource="True"/>

        <DataTemplate
x
:Key="InsanTemplate">

            <StackPanel>

                <TextBlock
Text
="{Binding
Adi
}"/>

                <TextBlock
Text
="{Binding
Soyadi
}"/>

            </StackPanel>

        </DataTemplate>

    </UserControl.Resources>

   
<Grid
x:Name="LayoutRoot"

DataContext
="{Binding
Source
={StaticResource
AllDataDataSource
}}" >

        <ListBox x:Name="listBox"
Margin="47,96,0,84"

ItemTemplate
="{StaticResource
InsanTemplate
}" ItemsSource="{Binding
All
}"
HorizontalAlignment="Left" Width="200"/>

        <Grid
DataContext
="{Binding
SelectedItem
, ElementName=listBox}"
Margin="310,94,76,186"
d
:DataContext="{Binding
All
[0]}" Background="White">

            <TextBlock HorizontalAlignment="Left"
VerticalAlignment="Top" Width="100" Height="16" Text="Adi"/>

            <TextBlock Text="{Binding
Adi
}"
HorizontalAlignment="Left" VerticalAlignment="Top" Width="150"
Height="16" Margin="104,0,0,0"/>

            <TextBlock
HorizontalAlignment="Left" VerticalAlignment="Top" Width="100"
Height="16" Margin="0,20,0,0" Text="Soyadi"/>

            <TextBlock Text="{Binding
Soyadi
}" HorizontalAlignment="Left" VerticalAlignment="Top"
Width="150" Height="16" Margin="104,20,0,0"/>

        </Grid>

    </Grid>

</UserControl>

Yukarıda tüm uygulamanın XAML kodunu inceleyebilirsiniz. Özellikle
renkli kısımlara bakacak olursak Blend'in neler yapmaya çalıştığını net
bir şekilde görebiliriz. İlk olarak en üstte bizim arkadaki
uygulamamızın bir XML namespace olarak Import edilmiş. Sonra söz konusu
yerden AllData sınıfından bir instance alınıp Resrouce'lar arasına
AllDataDataSource adı ile koyulmuş. Bu DataSource uygulama genelinde
Grid'e bağlanmış. Grid içerisinde ListBox ise All metoduna
bağlanmış. ListBox aldığı her Insan nesnesini yine Resource'lar
içerisinde tanımlı InstanTemplate ile gösterebiliyor.
InsanTemplate içerisinde ise her Insan'ın Property'leri uygun
kontrollere bağlanmış durumda. Son olarak detayları gösterecek olan
nesnelerin bulunduğu Grid'in DataContext'i bizim ListBox'ın
SelectedItem'ına element binding ile bağlanmış. SelectedItem zaten
bir Insan nesnesi olarak geleceğine göre Grid içerisindeki
kontrolleri de doğrudan bu Insan nesnesinin Property'lerine
bağlayabiliriz. Son ufak bir detay ise Grid'in DataContext'inin yanı
sıra bir de d:DataContext diye bir Property'sinin All
listesindeki Index numarası sıfır olan kayda bind edilmiş olması.
d: XML namespace'i tamamen design view için gerekli özellikleri
tanımlar. Yani tasarımcı Blend içerisinde uygulamayı görürken ve
uygulama çalışmazken bu Grid'in doğrudan All listesindeki ilk
nesneyi göstermesini sağlamak için Blend böyle bir kod eklemiş durumda.

Sonuç olarak gördüğünüz gibi aslında her iki tarafın da kurallara uyması
halinde Expression Blend ve Visual Studio ile beraber tasarımcılar ve
yazılımcıların beraber rahatça çalışması olması.

Hepinize kolay gelsin.