Silverlight 2.0 Beta 1 içerisinde DataGrid kullanımı!

0 dakikada yazıldı

8661 defa okundu

Düzenle

Silverlight 2.0 Beta 1 ile beraber gelen ilginç kontrollerden biri
de DataGrid kontrolüdür. Aslında kontrolün kendisinde herhangi bir
ilginçlik yok, ilginç olan WPF'in ilk sürümlerinde böyle bir kontrol
yokken Silverlight'ın ikinci sürümünde DataGrid'in geliyor olması. Bu
yazımızda Silverlight 2.0 Beta 1 ile DataGrid kullanımına
deyineceğiz.

Silverlight 2.0 projenizi Visual Studio 2008 ile yarattıktan sonra hemen
araç çubuğunda DataGrid kontrolü ile karşılaşabilirsiniz. Expression
Blend içerisinde ise varsayılan ayarlar ile gelmeyecektir. Bunun aslında
basit bir nedeni var; DataGrid gibi veri kontrolleri Silverlight 2.0
için harici bir Control Library olan System.Windows.Controls.Data
altında geliyor ve bu kütüphane normal şartlarda uygulamaları referans
olarak eklenmiş olmuyor. Eğer uygulamanıza bu sınıfı referans olarak
eklerseniz Blend içerisinde de gerekli seçenekler gelecektir. Visual
Studio içerisinde sahneye bir DataGrid yerleştirdiğinizde gerekli
referanslar otomatik olarak ekleniyor.

<UserControl
xmlns:my="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"  x:Class="SilverlightApplication25.Page"

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

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

    Width="400" Height="300">

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

      <my:DataGrid></my:DataGrid>

    </Grid>

</UserControl>

Yukarıdaki kodu incelediğinizde herhangi bir Silverlight uygulamasına
DataGrid yerleştirildiğinde en üst satırdaki XML namespace tanımını
görebilirsiniz. Söz konusu tanım veri kontrollerinin Assembly'lerine
bağlı. Böylece artık uygulamamızda veri kontrollerini kullanabiliriz.
Bunun bir sonucu olarak artık uygulamamızdan üretilecek XAP paketinde de
System.Windows.Controls.Data.dll dosyası bulunacaktır.

İlk olarak istemci tarafındaki kodumuz ile DataGrid içerisinde
gösterilmek üzere bir veri yığını yaratalım. Bu noktada siz
uygulamalarınızda rahatlıkla farklı web servislerinden çektiğiniz
verileri kullanabilirsiniz.

[VB]

    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 PStok As Boolean

        Public Property Stok() As Boolean

            Get

                Return PStok

            End Get

            Set(ByVal value As Boolean)

                PStok = value

            End Set

        End Property

 

        Sub New()

 

        End Sub

 

        Sub New(ByVal
adi As String, ByVal stok As Boolean)

            Me.Adi = adi

            Me.Stok = stok

        End Sub

 

    End Class

[C#]

    public class Urun

    {

 

        private string PAdi;

        public string Adi

        {

            get { return PAdi; }

            set { PAdi = value; }

        }

 

 

        private bool PStok;

        public bool Stok

        {

            get { return PStok; }

            set { PStok = value; }

        }

 

        public Urun()

        {

 

        }

 

        public Urun(string adi, bool stok)

        {

            this.Adi = adi;

            this.Stok = stok;

        }

 

    }

Yukarıdaki sınıf yapısını verimizi oluştururken kullanacağımız nesneler
olarak hazırladık. Silverlight 2.0'daki DataBinding WPF ile büyük bir
benzerliğe sahip. Özellikle LINQ ile beraber kullanıldığında nesneleri
kontrollere bind edebiliyor olmak büyük avantaj sağlıyor. Şimdi gelelim
bize geçici olarak veri yaratacak olan kodumuzu yazmaya.

[VB]

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

        Dim liste As New
System.Collections.Generic.List(Of
Urun)

        For x As Integer
= 0 To 9

            liste.Add(New Urun("Urun Adi" & x, (Math.Round(Rnd() * 1) -
1)))

        Next

        BirGrid.ItemsSource = liste

    End Sub

[C#]

        public Page()

        {

            InitializeComponent();

 

            System.Collections.Generic.List<Urun> liste = new System.Collections.Generic.List<Urun>();

            Random RastGele = new Random();

            for (int x = 0; x <= 9; x++)

            {

                liste.Add(new
Urun("Urun Adi" + x.ToString(),
Convert.ToBoolean(RastGele.Next(0,

    • 1)));

            }

            BirGrid.ItemsSource = liste;

        }

Kod içerisinde de gördüğünüz gibi elimizdeki veriyi doğrudan BirGrid
adındaki DataGridimizin ItemsSource özelliğine bağlıyoruz. Böylece
DataBinding işlemi tamamlanmış oldu. Fakat bağladığımız bu verinin
Grid içerisinde kolonlara yerleşmesi için tabi bizim "kolon"lara
ihtiyacımız var. Otomatik olarak veriye uygun kolon yaratılabilmesi için
DataGrid'in AutoGenerateColumns özelliğinin True olarak
ayarlanmış olması gerekiyor.

<UserControl
xmlns:my="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"  x:Class="SilverlightApplication25.Page"

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

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

    Width="400" Height="300">

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

    <my:DataGrid
x:Name="BirGrid"
AutoGenerateColumns="True"></my:DataGrid>

  </Grid>

</UserControl>

XAML kodumuzun son hali yukarıdaki gibi olmalı. Böylece uygulamamızı
çalıştırdığımızda aşağıdaki manzara ile karşılaşabiliriz.

Silverlight 2.0 içerisinde DataGrid görüntüsü.
Silverlight 2.0 içerisinde DataGrid görüntüsü.

İsterseniz alternatif satırların fon renklerini hatta kolonlar arası
çizgilerin renklerini bile tek tek belirleyebilirsiniz. Aşağıdaki kod
yapabileceğiniz renk değişikliklerine dair bir ipucu olabilir.

<UserControl
xmlns:my="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"

            x:Class="SilverlightApplication25.Page"

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

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

            Width="400"

            Height="300">

  <Grid
x:Name="LayoutRoot"

        Background="White">

    <my:DataGrid
x:Name="BirGrid"

                AutoGenerateColumns="True"

              ** ** AlternatingRowBackground="#FFFFFF00"

**               ** HorizontalGridlinesBrush="#FFD4FF00"

**               ** RowBackground="#FFE3E3E3"></my:DataGrid>

  </Grid>

</UserControl>

Kendi kolonlarımızı tanımlayalım!

Aslında AutoGenerateColumns özelliği bizim ASP.NET'teki GridView'den
de alışık olduğumuz bir özellik. Kolay bir kullanım sağlasa da çoğu
zaman bu özellik istediğimiz uygulamaları hazırlayabilmemiz için yeterli
değil. O nedenle gelin şimdi beraber bir DataGrid içerisinde kolonları
nasıl elle ayarlayabileceğimizi inceleyelim.

Eğer AutoGenerateColumns özelliğini True yapmazsanız hali
hazırda varsayılan ayarı zaten False olarak geliyor. O nedenle bir
önceki projemize devam edeceğimiz için ilk olarak ya
AutoGenerateColumns özelliğini XAML kodunuzdan silin ya da False
olarak ayarlayın.

Bir DataGrid'in üç çeşit kolonu olabilir;

Adlarından da anlaşılacağı üzere ikisi kendi isimlerindeki kontrolleri
kolonlara yerleştirirken TemplateColumn ise bize daha esnek bir yapı
sağlıyor. İlk olarak gelin TextBoxColumn ve CheckBoxColumn
kullanarak bir önceki adımdaki örneğimizin kolonlarını elle
tanımlayalım.

    <my:DataGrid
x:Name="BirGrid"

                AutoGenerateColumns="False"

                AlternatingRowBackground="#FFFFFF00"

                HorizontalGridlinesBrush="#FFD4FF00"

                RowBackground="#FFE3E3E3">

      <my:DataGrid.Columns>

        <my:DataGridTextBoxColumn
Header
="Adi"

                                 
DisplayMemberBinding="{Binding
Adi}
" />

        <my:DataGridCheckBoxColumn
Header
="Stokta Var?"

                                 
DisplayMemberBinding="{Binding
Stok}
" />

 

      </my:DataGrid.Columns>

    </my:DataGrid>

Kolonlarımızı ekledikten sonra her kolonun Header özelliğini
değiştirerek o kolonda gözükecek olan başlığı ayarlayabiliyoruz. Son
olarak da veri kaynağından hangi Property'nin söz konusu kolonda
gözükeceğini belirlemek için bir Binding kullanıyoruz. Görsel olarak
sonuç bir önceki örneğimizdeki ile aynı olacak fakat bu sefer kolonları
biz el ile tek tek ayarlamış olduk. Bunun getireceği esnekliği özellikle
TemplateColumn ile çok daha rahat görebiliriz.

Özel kolonlar : TemplateColumn

Özel bir kolon tanımlarken yapmamız gereken iki şey var; ilk olarak
kolonun normal görüntüsünü tanımlamak, ikincisi ise "edit" modundaki
görüntüsünü tanımlamak. Eğer ReadOnly özelliklerini değiştirmezseniz
normal şartlarda hem TextBoxColumn hem de CheckBoxColumn
üzerlerine tıklandıklarında içlerindeki verinin değiştirilebilmesine
olanak tanırlar. Hatta Binding Mode olarak da TwoWay
parametresini aktarırsanız arka planda Bind ettiğiniz List içerisinde
gerekli değişiklikler de otomatik olarak yapılır. Şimdi biz tüm bunları
bir TemplateColumn ile deneyeceğiz. Amacımız Stok bilgisi gösteren
kolonu biraz değiştirerek normalde içerisinde True veya False yazmasını
sağlamak. Yani normal şartlarda o kolonda bir CheckBox gözükmeyecek,
fakat kullanıcına kolona çift tıklar ve değeri değiştirmek isterse
karşınızda bu sefer bir CheckBox gelecek.

        <my:DataGridTemplateColumn Header="Stokta
Var?
">

          <my:DataGridTemplateColumn.CellTemplate>

            <DataTemplate>

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

            </DataTemplate>

          </my:DataGridTemplateColumn.CellTemplate>

          <my:DataGridTemplateColumn.CellEditingTemplate>

            <DataTemplate>

              <CheckBox
IsChecked="{Binding
Stok, Mode=TwoWay}
"></CheckBox>

            </DataTemplate>

          </my:DataGridTemplateColumn.CellEditingTemplate>

        </my:DataGridTemplateColumn>

Yukarıdaki kodu detaylı olarak incelemekte fayda var. Yarattığımız
TemplateColumn'un içerisinde bir CellTemplate, bir de
CellEditingTemplate var. Bu kolonun normal şartlardaki görüntüsü
CellTemplate, düzenleme modundaki görüntüsü ise CellEditingTemplate
içerisindeki şablona göre hazırlanacak. CellTemplate içerisinde
DataTemplate içinde sadece bir TextBlock koyuyoruz ve söz konusu
TextBlock'un da Text özelliğini Stok bilgisini bind
ediyoruz. Böylece normalde Stok bilgisi String olarak bu TextBlock
içerisinde gösterilecek. Gelelim CellEditingTemplate şablonunda; bu
şablon içerisinde de bir CheckBox kullanarak söz konusu CheckBox'un
IsChecked özelliğini Stok Property'sine Bind ederken Mode
olarak da TwoWay'i seçiyoruz. Böylece bu CheckBox üzerinde yapılan
değişiklikler elimizdeki List verimize yansıyacak, yani kaydedilecek.

Uygulamamızın tam XAML kodunu aşağıda inceleyebilirsiniz.

<UserControl
xmlns:my="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"

            x:Class="SilverlightApplication25.Page"

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

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

            Width="400"

            Height="300">

  <Grid
x:Name="LayoutRoot"

        Background="White">

    <my:DataGrid
x:Name="BirGrid"

                AutoGenerateColumns="False"

                AlternatingRowBackground="#FFFFFF00"

                HorizontalGridlinesBrush="#FFD4FF00"

                RowBackground="#FFE3E3E3">

      <my:DataGrid.Columns>

        <my:DataGridTextBoxColumn Header="Adi"

                                 
DisplayMemberBinding="{Binding
Adi}
" />

        <my:DataGridCheckBoxColumn Header="Stokta
Var?
"

                                 
DisplayMemberBinding="{Binding
Stok}
" />

        <my:DataGridTemplateColumn Header="Stokta
Var?
">

          <my:DataGridTemplateColumn.CellTemplate>

            <DataTemplate>

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

            </DataTemplate>

          </my:DataGridTemplateColumn.CellTemplate>

          <my:DataGridTemplateColumn.CellEditingTemplate>

            <DataTemplate>

              <CheckBox
IsChecked="{Binding Stok,
Mode=TwoWay}
"></CheckBox>

            </DataTemplate>

          </my:DataGridTemplateColumn.CellEditingTemplate>

        </my:DataGridTemplateColumn>

      </my:DataGrid.Columns>

    </my:DataGrid>

  </Grid>

</UserControl>

IValueConverter ile Binding'lere müdahale edin

Bir önceki örnek biraz saçma gelmiş olabilir. Kolon içerisinde doğrudan
True veya False yazıyor olmak pek hoş değil. Stok bilgisinden
bahsettiğimize göre True veya Flase yerine "Var" veya "Yok" yazdırsak
belki çok daha mantıklı olabilirdi. Kullanıcı satıra tıkladığında ise
yine karşısına düzenleme modunda bir CheckBox gelecektir. Bu işlemi
yapabilmemiz için bizim CellTemplate içerisindeki TextBlock'un
Binding'ine müdahale ederek "Eğer True geliyorsa VAR yazdır, gelmiyorsa
YOK yazdır
" diyebilmemiz gerekiyor. İşte tam da bu işlemi yapabilmek
için Silverlight 2.0 Beta 1 içerisinde ValueConverter yapılarını
kullanabiliyoruz.

[VB]

Public Class StokCevirici

    Implements Data.IValueConverter

 

    Public Function Convert(ByVal value As Object,
ByVal targetType As System.Type, ByVal parameter As Object,
ByVal culture As System.Globalization.CultureInfo) As Object
Implements
System.Windows.Data.IValueConverter.Convert

        If value Then

            Return "Var"

        Else

            Return "Yok"

        End If

    End Function

 

    Public Function ConvertBack(ByVal value As Object,
ByVal targetType As System.Type, ByVal parameter As Object,
ByVal culture As System.Globalization.CultureInfo) As Object
Implements
System.Windows.Data.IValueConverter.ConvertBack

        If value = "Var" Then

            Return True

        Else

            Return False

        End If

    End Function

End Class

[C#]

    public class StokCevirici :
System.Windows.Data.IValueConverter

    {

 

        object
System.Windows.Data.IValueConverter.Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)

        {

            if (bool.Parse(value.ToString()))

            {

                return "Var";

            }

            else

            {

                return "Yok";

            }

        }

 

        object
System.Windows.Data.IValueConverter.ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)

        {

            if (value.ToString() ==
"Var")

            {

                return true;

            }

            else

            {

                return false;

            }

        }

    }

İlk olarak yukarıdaki şekilde System.Windows.Data.IValueConverter
sınıfını implemente etmemiz gerekiyor. Bu şekilde bir Converter
yapısının her zaman bir Convert ve bir de ConvertBack
metodlarının bulunması şart. Bu metodlar aslında bizim elimizdeki True
veya False olan Boolean değerinin String'e çevireceğimiz ve Binding
için DataGrid'e göndereceğimiz veriyi oluşturmamıza olanak tanıyorlar.
Kod içerisinde de duruma göre parametre olarak gelen Boolean değeri
String'e veya tam tersine işlemler yapıyoruz. Sıra geldi bu
Converter yapısını XAML kodumuzda kullanarak Binding işlemine dahil
etmeye.

<UserControl
xmlns:my="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"

            x:Class="SilverlightApplication25.Page"

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

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

  **         ** xmlns:local="clr-namespace:SilverlightApplication25"

            Width="400"

            Height="300">

İlk olarak yukarıdaki şekilde XAML içerisinde kullanacağımız
Assembly'mizi tanımlıyoruz. Böylece Converter sınıfımızı rahatlıkla
kullanabileceğiz. Fakat işlemler bu kadarla bitmiyor. Tanımladığımız
Assembly içerisinde Convertor'ımızı da alarak sayfada Resource olarak
yerleştirmemiz şart.

  <UserControl.Resources>

    <local:StokCevirici x:Key="StokCevirici"
/>

  </UserControl.Resources>

Tüm bu işlemlerde Visual Studio'nun Intellisense yapısı size yardımcı
olacaktır. Artık XAML tarafında StokCevirici adını verdiğimiz
Converter yapımızı istediğimiz bir Binding için kullanmaya
hazırız.

<UserControl
xmlns:my="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"

            x:Class="SilverlightApplication25.Page"

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

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

            xmlns:local="clr-namespace:SilverlightApplication25"

            Width="400"

            Height="300">

  <UserControl.Resources>

    <local:StokCevirici x:Key="StokCevirici"
/>

  </UserControl.Resources>

  <Grid
x:Name="LayoutRoot"

        Background="White">

    <my:DataGrid
x:Name="BirGrid"

                AutoGenerateColumns="False"

                AlternatingRowBackground="#FFFFFF00"

                HorizontalGridlinesBrush="#FFD4FF00"

                RowBackground="#FFE3E3E3">

      <my:DataGrid.Columns>

        <my:DataGridTextBoxColumn Header="Adi"

                                 
DisplayMemberBinding="{Binding
Adi}
" />

        <my:DataGridCheckBoxColumn Header="Stokta
Var?
"

                                 
DisplayMemberBinding="{Binding
Stok}
" />

        <my:DataGridTemplateColumn Header="Stokta
Var?
">

          <my:DataGridTemplateColumn.CellTemplate>

            <DataTemplate>

              <TextBlock
****
Text="{Binding
Stok, Converter={StaticResource StokCevirici}}
" />

            </DataTemplate>

          </my:DataGridTemplateColumn.CellTemplate>

          <my:DataGridTemplateColumn.CellEditingTemplate>

            <DataTemplate>

              <CheckBox
IsChecked="{Binding Stok,
Mode=TwoWay}
"></CheckBox>

            </DataTemplate>

          </my:DataGridTemplateColumn.CellEditingTemplate>

        </my:DataGridTemplateColumn>

 

      </my:DataGrid.Columns>

    </my:DataGrid>

  </Grid>

</UserControl>

Uygulamanın son halinin tam kodunu yukarıdaki inceleyebilirsiniz.
Özellikle yarattığımız Converter'ın kullanım şekline dikkat etmekte
fayda var. Artık TextBlock içerisinde gösterilen veriler söz konusu
Converter'dan geçtikten sonra gösterileceği için ekranda "Var" veya
"Yok" yazıları yer alacak. Oysa kullanıcı çift tıklayarak değeri
değiştirmek istediğinde karşısına bir CheckBox çıkacak ve True veya
False olabilecek Boolean değeri değiştiriyor olacak.

Hepinize kolay gelsin.