DataForm kontrolüne hızlı bir şekilde göz atıldığında aslında ASP.NET'teki DetailsView
kontrolüne benzetilebilir. Bu önyargı ile hızlıca konumuza giriş yaparken gelin
ilk olarak bir Silverlight 3 projesine nasıl DataForm kontrolünü ekleyebiliriz
inceleyelim.
DataForm kontrolü sahnede...
DataForm kontrolü Silverlight ile beraber gelen harici kontrollerden biri.
Yani DataForm kontrolü Silverlight 3'ün RunTime'ında bulunmuyor. Öyle hemen
istediğimiz yerde anında kullanamıyoruz. Eğer bizim uygulamamız bu kontrolü
kullanmak istiyorsa ona ait DLL'i referans alarak kendi XAP dosyası içerisinde
taşımak zorunda. Tabi bu harici DLL'ler ile ilgili cachleme vs işlemleri de
mümkün fakat bu konuda makalemizin şimdilik dışında.
Durum böyle ise DataForm kontrolünü kullanabilmek için hemen Visual
Studio içerisinde yeni bir SL 3.0 projesi yaratıp projemize sağ tıklayarak "Add
Reference" diyip System.Windows.Controls.Data.DataForm'ı
referans olarak eklemeliyiz. Böylece artık bu DLL içerisindeki kontrolleri
kullanabiliriz. Fakat daha işimiz bitmedi. Projemize eklemiş olduğumuz bu
Assembly içerisindeki kontrolleri XAML tarafında veya Blend 3 içerisinde
kullanabilmemiz için ayrıca XAML tarafına da DLL'imizi tanıtmamız gerekiyor.
[XAML]
<UserControl x:Class="SilverlightApplication10.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300"
xmlns:dataControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm" >
<Grid x:Name="LayoutRoot" Background="White">
<dataControls:DataForm x:Name="birDataForm"></dataControls:DataForm>
</Grid>
</UserControl>
Yukarıda gördüğünüz şekli ile DLL'imizi dataControls adı
altında XAML tarafına da aldık. Sonrasında da içerisinde bulunduğumuz sayfadaki
Grid'in içine yine dataControls XML namespace'i üzerinden
giderek Assembly içerisinde DataForm sınıfından bir instance
alıyoruz. Artık sahnede bir DataForm var. Tüm bu işlemleri otomatik olarak
yapmak isterseniz Visual Studio içerisinde XAML dosyasını açarak araç çubuğundan
da DataForm kontrolünü sürükleyip sahneye bırakabilirsiniz. Visual Studio sizin
için otomatik olarak DLL'i referans alıp gerekli XAML tanımlamalarını da
yapacaktır. Bu noktada ufak bir detaya dikkat çekmek istiyorum. Şu an
Silverlight 3.0 Beta olduğu için Visual Studio içerisinde designer tarafında
desteği biraz zayıf. O nedenle araç çubuğundan herhangi bir kontrolü XAML
dosyanıza sürükleyip bırakmak isterseniz sadece kod tarafına bırakabileceğinizi
söylemem gerek.
Hemen bir veri bağlayalım!
Kontrolümüz artık sahnede olduğuna göre hemen bir veri bağlayarak neler
yapabiliyoruz göz atalım. İlk olarak bağlayacağımız veriyi temsil edecek olan
sınıfımızı yaratalım.
[VB]
Public Class Entities
Public Class
Urun
Private PAdi As String
Public Property
Adi() As String
Get
Return PAdi
End Get
Set(ByVal value As String)
PAdi = value
End Set
End Property
Private PSatis As Double
Public Property
Satis() As Double
Get
Return PSatis
End Get
Set(ByVal value As Double)
PSatis = value
End Set
End Property
End Class
End Class
[C#]
public class Entities
{
public class Urun
{
private string PAdi;
public string
Adi
{
get { return PAdi; }
set { PAdi = value; }
}
private double PSatis;
public double
Satis
{
get { return PSatis; }
set { PSatis = value; }
}
}
}
Gördüğünüz gibi sınıfımızın adı Urun ve içerisinde de iki
adet farklı Property var. Bu sınıfımızdan yola çıkarak birden çok Urun
yaratıp bunları da DataForm kontrolümüze veri kaynağı olarak vereceğiz. Ama
gelin bunun öncesinde tek bir Urun sınıfı yaratarak DataForm'a
verelim bakalım neler yapacak.
[VB]
Private Sub MainPage_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
birDataForm.CurrentItem = New Entities.Urun() With {.Adi = "Ürün Adi", .Satis = 20}
End Sub
[C#]
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
birDataForm.CurrentItem = new Entities.Urun { Adi = "Ürün Adi", Satis = 20 };
}
Daha önceden XAML tarafında yaratmış olduğumuz DataForm kontrolüne isim
olarak birDataForm ismini verdiğimiz için kod tarafında da aynı
isimle ulaşıp şimdilik DataForm'un CurrentItem özelliğine yeni
bir nesne atıyoruz. Söz konusu nesne daha önce tanımlamış olduğumuz Urun
sınıfının bir instance'ı.

DataForm içerisinde tek bir kaydın düzenlenmesi
Gördüğünüz üzere DataForm otomatik olarak kendisine bağlanan
veri içerisinde tüm Property'ler için hem Textblock ve Textbox'lar
yerleştirebiliyor hem de söz konusu Property'lerin adlarını da yanına yazarak
aslında kabaca bir veri giriş ve düzenleme ekranı oluşturuyor. DataForm
içerisinde sol üstte bulunan Edit düğmesine tıklarsanız ortaya veriyi
düzenleyebileceğiniz bir ekran gelirken "Save" düğmesi de hemen altta kendini
gösteriyor. Tabi ki bu aşamadan sonra özelleştirilmesi gereken birçok nokta var.
İşte biz de makalemizin devamında bu noktalara değineceğiz.
MetaData aşkı!
Eğer ASP.NET Dynamic Data projeleri üzerine biraz çalışma şansınız olduysa
veri kaynağı olarak kullanılan sınıflara verilen MetaData'lar ile beraber birçok
şeyin ayarlanabildiğini hatırlayacaksınız. DataForm ile beraber çalışırken de
aslında çoğu kuralı MetaData'lar ile DataForm'a bağlayacağımız veri kaynağı
seviyesinde ayarlamamız gerekiyor. Örneğin yukarıdaki projemizde Urun adındaki
nesnemizi tanımlarken Adi ve Satis
Property'lerinde tabi ki Türkçe karakterler kullanmadık. Oysa DataForm bu
Property'leri istemci tarafına açarken belki de Türkçe karakterler de içeren
düzgün isimleri açmalı değil mi?
[VB]
Public Class Entities
Public Class Urun
Private PAdi As String
<System.ComponentModel.DataAnnotations.Display(Name:="Adı")> _
Public Property Adi() As String
Get
Return PAdi
End Get
Set(ByVal value As String)
PAdi = value
End Set
End Property
Private PSatis As Double
<System.ComponentModel.DataAnnotations.Display(Name:="Satış")> _
Public Property Satis() As Double
Get
Return PSatis
End Get
Set(ByVal value As Double)
PSatis = value
End Set
End Property
End Class
End Class
[C#]
public class Entities
{
public class Urun
{
private string PAdi;
[System.ComponentModel.DataAnnotations.Display(Name =
"Adı")]
public string Adi
{
get { return PAdi; }
set { PAdi = value; }
}
private double PSatis;
[System.ComponentModel.DataAnnotations.Display(Name =
"Satış")]
public double Satis
{
get { return PSatis; }
set { PSatis = value; }
}
}
}
Yukarıdaki kod içerisinde Urun sınıfımızı tanımlarken neleri
değiştirediğimize dikkat edelim. Her bir Property'i tanımlarken bir de MetaData
veriyoruz. System.ComponentModel.DataAnnotations sınıfı altında
kullanabileceğiniz bir çok farklı MetaData'yı bulabilirsiniz. Bunların
bazılarına makalemiz içerisinde göz atacağız. Şu an için Display
MetaData'sını vererek söz konusu Property'lerin DataForm
tarafından hangi isimle gösterilmesi gerektiğini belirtiyoruz. Tabi ki bu
noktada istediğimiz gibi Türkçe karakterler kullanabiliriz. Bundan sonraki örnek
kodlarda Urun sınıfının tüm tanımını değil sadece
MetaData koyduğumuz satırların etrafını yazacağım.
[VB]
<System.ComponentModel.DataAnnotations.Display(Name:="Satış", Description:="Bu satış değeridir")> _
Public Property Satis() As Double
Yukarıdaki şekli ile tanımlanan bir Display MetaData'sında ek olarak bir de
Description verisi bulunuyor. Bu parametreye herhangi bir değer verilmesi
halinde DataForm içerisinde bu Property'nin yanında bir ünlem işareti
belirecektir. Kullanıcılar söz konusu ünlem işaretinin üzerine fareleri ile
geldiklerinde ise açıklamanızı görebilirler.

MetaData içerisinde Description yer alırsa...
Şu ana kadar yaptığımız işlemlerin hepsinde belki de en sinir bozucu
noktalardan biri DataForm içerisinde tüm Property'lerin sınıf tanımındaki sıra
ile gösteriliyor olmasıdır. Aslında bu sırayı da değiştirebiliyoruz.
[VB]
Private PAdi As String
<System.ComponentModel.DataAnnotations.Display(Order:=1)> _
Public Property Adi() As String
Get
Return PAdi
End Get
Set(ByVal value As String)
PAdi = value
End Set
End Property
Private PSatis As Double
<System.ComponentModel.DataAnnotations.Display(Name:="Satış", Description:="Bu satış değeridir",
Order:=0)> _
Public Property Satis() As Double
Get
Return PSatis
End Get
Set(ByVal value As Double)
PSatis = value
End Set
End Property
Display MetaData'sını tanımlarken verebileceğiniz Order
parametresi doğrudan bu Property'lerin hangi sıra ile DataForm içerisinde
gösterileceğini belirliyor. Sıfırdan başlayarak vereceğiniz bu sayılarla
küçükten büyüğe doğru gidecek sırada Property'ler ekrana getirilecektir. Bizim
örneğimizde üstte Satis altta Adi
parametreleri yer alıyor.
Binding yollarında...
İlk örneğimizde DataForm'a bağladığımız nesne kod tarafında içerisinde
bulunduğu scope dışında yaşayamayacağı için pek anlamlı bir örnek olmamıştı.
DataForm içerisinde edit işlemi yapılsa da söz konusu bağlı değişken arkada
yaşamadığı için edit işleminin de anlamı kalmıyor. Fakat eğer DataForm'a
bağladığınız değişkenleri kod tarafında sürekli canlı tutarsanız DataForm
içerisindeki değişikliklerin doğrudan nesneye yansıtıldığını da görebilirsiniz.
Duruma göre bu işlevselliği değiştirmek veya bazen arka taraftaki nesnede
bulunan bazı Property'leri DataForm içerisinde göstermemek de isteyebilirsiniz.
Örneğin bizim Urun nesnesinin bir PK property'si olsaydı kesin onu göstermek
istemezdir.
[VB]
<System.ComponentModel.Bindable(False)> _
Public Property Adi() As String
Yukarıdaki gibi herhangi bir Property'yi doğrudan Bindable False olarak
işaretleyebilirsiniz. Böylece söz konusu Property hiçbir şekilde bağlı olduğu
kontroller tarafından gösterilmeyecektir. Diğer yandan bu Property'nin
gösterilmesi fakat değerinin değiştirilemesini isterseniz bu sefer de aşağıdak
şekilde Bindable'a ikinci bir parametre vererek tek yönlü veri bağlantısı
oluşturabilirsiniz.
[VB]
<System.ComponentModel.Bindable(True, ComponentModel.BindingDirection.OneWay)> _
Public Property Adi() As String
Yukarıdaki şekli ile bu Property DataForm'un edit modunda gözükse de değeri
değiştirilemeyecektir.
Ya Validation gerekirse?
Belki de DataForm kontrolünün en can alıcı noktalarından biri tüm validasyon
işlemlerini de kısmen MetaData üzerinden yapabiliyor olmamız. Örneğin bazı
Property'lerin kullanıcı tarafından boş geçilememesini isteyebilirsiniz. Bu ve
bu gibi tüm Validation işlemleri için yine System.ComponentModel.DataAnnotations
sınıfı altındaki tanımlardan faydalanabiliriz.
[VB]
<System.ComponentModel.DataAnnotations.Required(ErrorMessage:="Boş geçilemez")> _
Public Property Adi() As String
Yukarıdaki örnek kodda da görebileceğiniz üzere Required
olarak işaretlediğimiz Adi Property'sine bir de
ErrorMessage vermişiz. DataForm kontrolü bu Property ile ilgili gerekli
validasyonları yapmakla kalmayacak, herhangi bir sorun olduğunda MetaData
içerisinde tanımladığımız hatayı da güzel bir şekilde kullanıcıya gösterecek.

Basit bir validasyon örneği!
Validasyon yöntemlerinden bazıları bir önceki örneğimizdeki gibi hazır bir
şekilde tanımlanmış bizim kullanımızı bekliyor. Bunlardan biri de doğrudan
sayısal değerlerin alabilecekleri değer aralığını kontrol eden Range
sınıfı.
[VB]
<System.ComponentModel.DataAnnotations.Range(1, 10, ErrorMessage:="Aman!")> _
Public Property Satis() As Double
Range MetaData'sını biz örneğimizde anlamlı olması açısından Satis
Property'sine verelim. Artık yukarıdaki tanımlama ile beraber Satis Property'si
kesinlikle 1 ile 10 arasında olmak zorunda. Aksi durumda MetaData içerisinde
tanımladığımız ErrorMessage kullanıcıya gösterilecektir.
[VB]
<System.ComponentModel.DataAnnotations.StringLength(10)> _
Public Property Adi() As String
Hazır gelen kontrollerden biri de StringLenght kontrolü. Bu MetaData ile
beraber söz konusu Property'e atanabilecek metin uzunluğunun en yüksek değerini
tanımlamış oluyoruz. Böylece kullanıcılar daha yüksek değerler girdiğinde eğer
tanımlanmış ise özel hata mesajları da gösterilebiliyor.
Eğer isterseniz tüm bu validasyonların yanı sıra daha karmaşık RegularExpression yapıları da kullanabilirsiniz. Bizim örneğimizde varsayalım ki
kullanıcıların ürünlere isim verirken hep büyük harf ile başlamalarını istiyoruz.
Bu durumda aşağıdaki gibi bir RegEx tanımlamasını işimizi görecektir.
[VB]
<System.ComponentModel.DataAnnotations.RegularExpression("^[A-Z]+[a-zA-Z]*$", ErrorMessage:="Büyük harfle başlamalı")> _
Public Property Adi() As String
Hardcore Validasyon?
Bazı durumlarda validasyon ile ilgili RegEx'ler de işinizi görmeyebilir.
Bizim örneğimizde bu duruma uygun anlamlı bir senaryo yaratmak zor olsa da
diyelim ki ürünlerimiz A harfi ile başlıyorsa fiyatlarının kesinlikle 10 ile 20
arasında olması gerekiyor. Bu senaryoyu gerçek hayata taşırken aslında farklı
Property'lerin farklı iş kuralları ile kontrol edilmesi gerektiğini de
düşünebilirsiniz. Böyle bir durumda tamamen farklı bir mekanizma kullanabilmek
için CustomValidation yapısı bizi bekliyor.
[VB]
Public Class Kontrol
Public Shared Function UrunKontrol(ByVal BirUrun As Urun) As Boolean
If BirUrun.Adi.StartsWith("A") Then
If BirUrun.Satis > 10 And BirUrun.Satis < 20 Then
Return True
Else
Return False
End If
Else
Return True
End If
End Function
End Class
[C#]
public class Kontrol
{
public static bool UrunKontrol(Urun BirUrun)
{
if (BirUrun.Adi.StartsWith("A"))
{
if (BirUrun.Satis > 10 & BirUrun.Satis < 20)
{
return true;
}
else
{
return false;
}
}
else
{
return true;
}
}
}
Yukarıdaki gördüğünüz kod içerisinde Kontrol adında bir
sınıfın içinde Shared / Static olarak tanımlanmış bir Validasyon metodu
bulunuyor. Metod aslında alıştığımız .NET metodlarından farklı değil.
UrunKontrol adını verdiğimiz bu metod kendisine parametre olarak
verilen bir Urun nesnesini kontrol ederek geriye True
veya False şeklinde Valid / Uygundur veya InValid / Uygun
Değildir mesajı döndürmüş oluyor. Bu hazırladığımız validasyon metodunun
herhangi bir Urun nesnesine uygulanması için ise Urun
nesnesinin tanımına ufak bir MetaData eklemesi yeterli olacaktır.
[VB]
<System.ComponentModel.DataAnnotations.CustomValidation(GetType(Kontrol), "UrunKontrol", ErrorMessage:="Olmadı!")> _
Public Class Urun
[C#]
[System.ComponentModel.DataAnnotations.CustomValidation(typeof(Kontrol), "UrunKontrol", ErrorMessage = "Olmadı!")]
public class Urun
{
}
CustomValidation olarak tanımladığımız bu kontrol
mekanizmasını sınıfımıza bağlarken ilk olarak validasyon yapacak olan sınıfın
tipini veriyoruz. Sonrasında bu sınıf içerisinde hangi metodun kullanılacağını
bir String parametre olarak verip bir de eğer istiyorsak validasyon işlemi
False döndürdüğünde gösterilmek üzere ErrorMessage
ayarlıyoruz. İsterseniz bu mekanizmayı sınıf bazında değil doğrudan Property
bazında da kurabilirsiniz.
Herşey kontrol altında...
Tüm bahsettiğimiz validasyon sistemlerine ek olarak bazen bir ürün
düzenlenmesi ile ilgili istemci tarafında DataForm ile yaratılan süreçlere
müdahale etmek de isteyebilirsiniz. Örneğin bir ürün kaydedilirken adı boş ise
belki ona varsayılan bir isim vermek isteyeceksiniz veya bir ürünün kayıt moduna
geçildikten sonra herhangi bir değişiklik yapılmadan kayıt modundan çıkılmasını
engellemek de isteyebilirsiniz. Bu gibi daha birçok senaryo olabilir.
[VB]
Public Class Urun
Implements ComponentModel.IEditableObject
Private PAdi As String
Public Property Adi() As String
Get
Return PAdi
End Get
Set(ByVal value As String)
PAdi = value
End Set
End Property
Private PSatis As Double
Public Property Satis() As Double
Get
Return PSatis
End Get
Set(ByVal value As Double)
PSatis = value
End Set
End Property
Public Sub
BeginEdit() Implements System.ComponentModel.IEditableObject.BeginEdit
End Sub
Public Sub
CancelEdit() Implements System.ComponentModel.IEditableObject.CancelEdit
End Sub
Public Sub
EndEdit() Implements System.ComponentModel.IEditableObject.EndEdit
End Sub
End Class
[C#]
public class Urun :
IEditableObject
{
private string PAdi;
public string Adi
{
get { return PAdi; }
set { PAdi = value; }
}
private double PSatis;
public double Satis
{
get { return PSatis; }
set { PSatis = value; }
}
public void
BeginEdit()
{
throw new NotImplementedException();
}
public void
CancelEdit()
{
throw new NotImplementedException();
}
public void
EndEdit()
{
throw new NotImplementedException();
}
}
Kendi sınıfınıza IEditableObject interface'ini implemente
ettiğiniz anda artık sınıfınızın BeginEdit, CancelEdit
ve EndEdit gibi durumları olacak. Bu durumlara dair kod
bloklarına yazacağınız kodlar edit işlemi başladığında, iptal edildiğinde veya
bittiğinde çalıştırılacaktır. Böylece siz de bu süreçlerde nesne ile ilgili
değişiklikleri rahatlıkla yapabilirsiniz.
Çoklu kayıt desteği de var.
DataForm kontrolünü epey karıştırmış olsak da aslında hiç
bakmadığımız bir özelliği var. Örneklerimizin başından beridir sadece tek bir
nesne yarattık ve DataForm'un CurrentItem'ına atadık. Oysa
DataForm
kontrolünün ItemsSource'una da birden çok nesne içeren listeler
bağlanabilir.
[VB]
Private Sub MainPage_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
Dim liste As New System.Collections.ObjectModel.ObservableCollection(Of Entities.Urun)
liste.Add(New Entities.Urun() With {.Adi = "Ürün Adi", .Satis = 20})
liste.Add(New Entities.Urun() With {.Adi = "Ürün Adi2", .Satis = 30})
liste.Add(New Entities.Urun() With {.Adi = "Ürün Adi3", .Satis = 40})
birDataForm.ItemsSource = liste
End Sub
[C#]
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
System.Collections.ObjectModel.ObservableCollection<Entities.Urun> liste = new System.Collections.ObjectModel.ObservableCollection<Entities.Urun>();
liste.Add(new Entities.Urun { Adi = "Ürün Adi", Satis = 20 });
liste.Add(new Entities.Urun { Adi = "Ürün Adi2", Satis = 30 });
liste.Add(new Entities.Urun { Adi = "Ürün Adi3", Satis = 40 });
birDataForm.ItemsSource = liste;
}
Kodumuzda bu sefer tamamen deneme amaçlı olarak içerisinde birden çok
Urun bulunan bir ObservableCollection kullanıyoruz.
Uygulamamızı çalıştırdığımıda DataForm kontrlünün sağ üstünde
navigasyon kontrolleri de yerini alıyor. Böylece artık DataForm
kontrolü içerisinde birden çok nesnenin de gezilerek düzenlenebileceğini görmüş
olduk.

Çoklu kayıt düzenleme ekranı.
Yukarıdaki ekran görüntüsünde sağ üst köşede gördüğünüz düğmeler sadece
kayıtlar arasında gezintiyi sağlamıyor. Ayrıca bulunan kaydın
düzenlenebilmesinin yanı sıra yeni bir kayıt eklenebilmesini hatta
silinebilmesini de sağlayabiliyorlar. Hali hazırda nesnemize bir
ObservableCollection bağladığımız için zaten tüm değişiklikler otomatik olarak
nesneye de yansıyacaktır.
AutoGenerateFields ?
Sanırım ASP.NET ile biraz uğraşan herkes AutoGenerateFields deyince ne demek
istediğimi anlayacaktır. Bir DataForm'un normal şartlarda kendisine verdiğimiz
veriye uygun şekilde gerekli TextBox vs kayıt düzenleme kontrollerini otomatik
olarak yaratmasını sağlayan özellik AutoGenerateFields'in varsayılan değeri olan
"True" değerinde saklı. Eğer AutoGenerateFields özelliğini
False olarak ayarlarsanız artık veri kaynağından gelen her
verinin ne şekilde görsel ekrana yansıtılacağını tek tek sizin ayarlamanız
gerekecektir. Tabi bu durum da bazı senaryolarda özelleştirme adına şart oluyor.
Şimdi gelin bu konunun detaylarına bakalım.
[XAML]
<dataControls:DataForm AutoGenerateFields="False"
x:Name="birDataForm">
<dataControls:DataForm.Fields>
<dataControls:DataFormCheckBoxField />
<dataControls:DataFormComboBoxField />
<dataControls:DataFormDateField />
<dataControls:DataFormTemplateField />
<dataControls:DataFormTextField />
</dataControls:DataForm.Fields>
</dataControls:DataForm>
Yukarıdaki kod çalışır bir kod olmayacaktır. Fakat kabaca bir DataForm'un
içerisinde gösterilecek verilerin ayarlanması ile ilgili kullanabileceğimiz
Field tiplerini ve DataForm içerisine nasıl yerleştirebileceğimizi
inceleyebilirsiniz. Bu Field tiplerinin her biri aslında farklı veri tiplerini
hedefliyorlar. Örneğin CheckBoxField Boolean
tipindeki verilerin gösterimi için rahatlıkla kullanılabilirken
TextField ise metin tabanlı ve özünde TextBox olarak gösterilecek
verileri temsil edecektir. Eğer bu Field tipleri size yeterli gelmiyorsa ve
kendi özel Field tasarımınızı yaratmak istiyorsanız bu sefer de
DataFormTemplateField'i kullanabilirsiniz.
[XAML]
<dataControls:DataForm
AutoGenerateFields="False"
x:Name="birDataForm">
<dataControls:DataForm.Fields>
<dataControls:DataFormTextField
FieldLabelContent="Kayıt Adı"
Binding="{Binding Adi}" />
<dataControls:DataFormTextField
FieldLabelContent="Satış Sayısı"
Binding="{Binding Satis}" />
</dataControls:DataForm.Fields>
</dataControls:DataForm>
Bir önceki adımda veri bağlantısını da yaptığımız DataForm üzerinden
ilerlersek ilk olarak AutoGenerateFields özelliğini
False olarak ayarlayıp sonrasında da iki tane TextField
ekliyoruz. Her bir TextField'in veri kaynağından hangi veriyi
alıp göstereceğini belirlemek için tabi ki veri kaynağımız olan nesnelerin
property'lerine ait adları vermemiz gerekiyor. Bu aşamada her bir Field'in
Binding özelliğine bir Binding atıyoruz ve Property
adı ile veri bağlantısını da tamamlıyoruz. Son olarak yine her bir TextField'e
de FieldLabelContent vererek bu Field'ler için yaratılacak
TextBox'ların yanına konacak Label'ların da içeriğini belirlemiş oluyoruz.
Ayrıca isterseniz FieldLabelPosition gibi Field'lere ayrı
farklı özellikleri de değiştirerek ana görsel öğelerin dizilimine müdahale
edebilirsiniz.
Eğer DataForm kontrolüne bağladığınız nesnelerin çok sayıda Property'si varsa
bunları belirli gruplar ve altbaşlıklar ile de göstermek isteyebilirsiniz. Bunun
için DataFormFieldGroup nesnesini kullanabilir hatta bu
grupların arasına da DataFormSeparator'lar koyabilirsiniz.
[XAML]
<dataControls:DataForm
AutoGenerateFields="False"
x:Name="birDataForm">
<dataControls:DataForm.Fields>
<dataControls:DataFormHeader
Content="Düzenlenecek şeyler" />
<dataControls:DataFormSeparator />
<dataControls:DataFormFieldGroup
Orientation="Horizontal">
<dataControls:DataFormTextField
FieldLabelPosition="Top"
FieldLabelContent="Kayıt Adı"
Binding="{Binding Adi}" />
<dataControls:DataFormTextField
FieldLabelPosition="Top"
FieldLabelContent="Satış Sayısı"
Binding="{Binding Satis}" />
</dataControls:DataFormFieldGroup>
</dataControls:DataForm.Fields>
</dataControls:DataForm>
Yukarıdaki kod içerisinde ilk olarak bir FormHeader
bulunuyor. Sonrasında bir Separator da kullandıktan sonra
elimizdeki TextField'leri bir Fieldgroup
içerisine aldık. FieldGroup'un Orientation
özelliğini de Horizontal yaptığımızda artık bu grup
içerisindeki kayıt düzenleme nesneleri yan yana gösterilecektir.

Özelleştirilmiş bir DataForm kontrolü.
Daha da özelleştirelim, daha da!
Eğer yukarıdaki Field yapılarını özelleştirmek sizin ihtiyaçlarınızı
gidermediyse aslında bir adım daha ileri giderek tüm görsel yapıyı değiştirme
şansınız da var. Bunun için artık DataForm'un DisplayTemplate ve
EditTemplate özelliklerine eğilmemiz şart.
[XAML]
<dataControls:DataForm
AutoGenerateFields="False"
x:Name="birDataForm">
<dataControls:DataForm.HeaderTemplate>
<DataTemplate></DataTemplate>
</dataControls:DataForm.HeaderTemplate>
<dataControls:DataForm.DisplayTemplate>
<DataTemplate></DataTemplate>
</dataControls:DataForm.DisplayTemplate>
<dataControls:DataForm.EditTemplate>
<DataTemplate></DataTemplate>
</dataControls:DataForm.EditTemplate>
<dataControls:DataForm.InsertTemplate>
<DataTemplate></DataTemplate>
</dataControls:DataForm.InsertTemplate>
</dataControls:DataForm>
Yukarıda gördüğünüz şekilde düzenlenen Template / Şablon yapıları birer
DataTemplate olarak tanımlanır ve bu şablonlar içerisinde
tanımlı görsel tasarımlar doğrudan DataForm kontrolü tarafından kullanılır.
[XAML]
<dataControls:DataForm
AutoGenerateFields="False"
x:Name="birDataForm">
<dataControls:DataForm.DisplayTemplate>
<DataTemplate>
<StackPanel>
<TextBlock
Text="{Binding Adi}"></TextBlock>
<TextBlock
Text="{Binding Satis}"></TextBlock>
</StackPanel>
</DataTemplate>
</dataControls:DataForm.DisplayTemplate>
<dataControls:DataForm.EditTemplate>
<DataTemplate>
<StackPanel>
<TextBox
Text="{Binding Adi}"></TextBox>
<TextBox
Text="{Binding Satis}"></TextBox>
</StackPanel>
</DataTemplate>
</dataControls:DataForm.EditTemplate>
</dataControls:DataForm>
Yukarıdaki XAMl içerisinde DataForm kontrolümüzün DisplayTemplate
ve EditTemplate şablonlarına basit birer StackPanel
yerleştiriyoruz. Bu StackPanel'ler içerisinde DisplayTemplate'te TextBlock'lar
var, EditTemplate'te ise TextBox'lar var. Tüm
bu kontrollerin Text özellikleri veri kaynağından uygun
Property'lere bağlı durumda. Veri bağlama işlemini yine klasik Binding
sistemi ile yapıyoruz. Kontrol normalde TextBlock'ları gösterirken düzenleme
moduna geçince ise EditTemplate içerisindeki TextBox'ları gösterecektir. Tabi
siz örneklerinizde basit birer StackPanel yerine çok daha özelleştirilmiş görsel
tasarımlar kullanabilirsiniz.
Sonuç
Görüldüğü üzere DataForm kontrolü kendisinden beklenenden çok daha fazlasını
sunabilecek bir kontrol olarak karşımızda. İş uygulamalarında sürekli
hazırladığınız çoğu formun Silverlight içerisinde rahatlıkla ve en önemlisi de
hızlı bir şekilde oluşturulabilmesini sağlıyor. İster basit ister karışık
validasyon kurallarınız olsun, ister basit ister karışık ve özelleştirilmiş bir
tasarımınız olsun DataForm kontrolü her durumda size uyum sağlayabilecek şekilde
tasarlanmış. Eh hadi ;) Sıra sizde...
Hepinize kolay gelsin....