İçeriğe geç

WPF Binding Nedir, Binding Modları ve Value Converter

Uzun zamandır nasıl başlasam diye düşündüğüm WPF serisine sonunda Binding nedir ve Binding modlarından başlamaya karar vererek, adım atmış bulunmaktayım.

Nedir bu Binding?

Kabaca iki özellik arasındaki bağlantıdır diyebiliriz. Biraz daha açarsak kontroller arasında verilerin birbirlerine bağlanarak beraber çalışmalarını sağlayan yapıdır diyebiliriz.

wpf-bindings

Yukarıdaki şemadan da anlaşılacağı üzere bazı durumlarda OneWay(Tek Taraflı) kaynaktan -> hedefe veya TwoWay(Çift Yönlü) hedeften de->kaynağa verinin aktarılmasını isteyebiliriz.

Hemen basit bir kaç örnek vermek gerekirse:

  • Bir TextBox’a girilen verinin Text özelliğinin aynı anda Label’ın Content özelliğine bağlanmasını isteyebilirsiniz.
  • Bir TextBox’a maximum 40 karakter uzunluğunda metin girilmesini istiyorsunuz ve kullanıcı her karakter girdiğinde eş zamanlı olarak kalan karakter uzunluğunu göstermek isteyebilirsiniz.
  • Bir ComboBox içerisine eklediğiniz renk isimlerinden yola çıkarak seçilen her renk’i window’un background’una anlık olarak bind edebilirsiniz.

Bu gibi durumlarda binding mekanizması imdadınıza yetişecektir.

Binding Modları:

MOD AÇIKLAMA
OneWay  Adından da anlaşılacağı üzere tek taraflı bir bağlama modudur. Kaynaktan hedefe doğru bağlama söz konusudur. Kaynakdaki bir değişiklik hedefin bağlanan özelliği üzerinde de etki edecektir.
TwoWay  Burada ise hedeften kaynağa doğruda çift yönlü bir bağlama söz konusudur.
OneTime  Burada kaynaktan hedefe doğru sadece bir kez bağlama işlemi söz konusudur.
OneWayToSource  Hedeften kaynağa doğru bir bağlama söz konusudur. Hedefdeki bir değişiklik kaynak üzerinde etki edecektir.
Default  Bu mod ise bağımlılık özelliğine göre değişiklik göstermektedir. Yani kullanıcının set edebileceği TextBox, CheckBox gibi kontroller için varsayılan olarak TwoWay, diğerleri için ise OneWay dir.

Hemen bir örnek ile devam edelim. Yukarıda bahsettiğimiz gibi bir TextBox’umuz olsun ve içerisine maksimum olarak 40 karakter girilmesini sağlayalım ve bir Label üzerinde geriye kalan karakter sayısını gösterelim.

<Window x:Class="WPFBinding.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WPFBinding"
        Title="{Binding ElementName=txtInput, Path=Text}" Height="150" Width="270">
    <Window.Resources>
        <local:MaxLengthDisplayerConverter x:Key="maxLengthDisplayerConverter" />
    </Window.Resources>
    <Grid>
        <TextBox x:Name="txtInput" MaxLength="40"
                 HorizontalAlignment="Left" 
                 Height="23" 
                 Margin="10,10,0,0" 
                 TextWrapping="Wrap" 
                 Text="Eş zamanlı bind oluyorum!" 
                 VerticalAlignment="Top" 
                 Width="153"/>
        <Label x:Name="lblInput" Content="{Binding ElementName=txtInput, Path=Text.Length, Converter={StaticResource maxLengthDisplayerConverter}, ConverterParameter=40}"
               HorizontalAlignment="Left" 
               Margin="10,38,0,0" 
               VerticalAlignment="Top" 
               RenderTransformOrigin="2.974,1.962" 
               Width="153"/>
    </Grid>
</Window>

Tanımlamış olduğumuz txtInput isimli kontrolümüzün MaxLength özelliğini 40 olarak belirliyoruz ve lblInput isimli kontrolün ise Content özelliğine txtInput‘un Text.Length‘ini bind(bağlamak) ediyoruz. Buradaki amaç: txtInput‘a girilen metnin uzunluğuna erişebilmek ve custom olarak yazdığımız ValueConverter aracılığı ile MaxLength‘den kalan karakter sayısını hesaplayıp Label içerisinde gösterebilmek.

Buradaki örneğimizde txtInput ile lblInput arasında bir OneWay binding modu söz konusudur. Çünkü yukarıda bahsetmiştik default olarak özelliklerin bağımlılıklarına göre bu kod değişiklik göstermekteydi. Burada ise txtInput‘un Text.Length özelliği ise read-only bir propertydir. Herhangi bir set durumu söz konusu olmayacağı için default OneWay olacaktır.

Binding tanımlamalarını {} küme parantezleri ile  gerçekleştiriyoruz. Eğer bir ValueConverter ile uğraşmayıp burada sadece txtInput içine girilen metni eş zamanlı olarak lblInput içerisinde göstermek isteseydik:

Content="{Binding ElementName=txtInput, Path=Text}"

dememiz yeterli olacaktı.  Örnek olması açısından dikkat ederseniz Window‘un Title özelliğine txtInput‘un Text‘ini bind etmiş durumdayız.

Şimdi hemen ValueConverterdeki kodlarımıza bir göz atalım.

Not: Binding işlemi yaparken Converterimizi StaticResource üzerinden gösterdiğimiz için yukarıdaki nod üzerinde Window.Resources tagları arasında tanımlamasını yapmalıyız. Code tarafında oluşturduğumuz converter’e ulaşabilmek için ise namespace‘inide Window‘un xmlns:local attributü ile belirtmeliyiz, benim projemin namespace’i WPFBinding.

MainWindow’un view code kısmına baktığımızda ise hesaplama için IValueConventer interface’ini implemente ederek custom bir ValueConverter oluşturduk.

using System;
using System.Windows;
using System.Windows.Data;

namespace WPFBinding
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }

    public class MaxLengthDisplayerConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            try
            {
                int maxLength = Int32.Parse(value.ToString());
                int enteredLength = Int32.Parse(parameter.ToString());

                return (enteredLength - maxLength);
            }
            catch
            {
                return null;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

}

Uygulamamızın ekran görüntüsü aşağıdaki gibidir.

binding-test

Value Converter Nedir?

Birbirinden farklı iki özelliği (yukarıda yaptığımız gibi lblInput’un Content özelliğine txtInput’un Text.Length özelliğine bind ettik) bind etmek istediğimizde aralarındaki bağlantıyı sağlayan yapıdır. Aralarındaki tip dönüşümlerini yapabilmemize olanak sağlamaktadır.

Custom bir Value Converter implementasyonunu ve kullanımını yukarıdaki örneğimizde görmüştük, şimdide en çok kullanılan value converterlerden BooleanToVisibilityConverter kullanımına hemen bir bakalım:

<Window x:Class="WPFBinding.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="{Binding ElementName=txtInput, Path=Text}" Height="150" Width="270">
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="booleanToVisibilityConverter"/>
    </Window.Resources>
    <Grid>
        <CheckBox x:Name="chckShow" Content="Göster" IsChecked="True" Margin="10,11,-10,-11" />
        <TextBox x:Name="txtInput"
                 Visibility="{Binding ElementName=chckShow, Path=IsChecked, Converter={StaticResource booleanToVisibilityConverter}}"
                 HorizontalAlignment="Left" 
                 Height="23" 
                 Margin="10,35,0,0" 
                 TextWrapping="Wrap" 
                 Text="Eş zamanlı bind oluyorum!" 
                 VerticalAlignment="Top" 
                 Width="153"/>
    </Grid>
</Window>

Örnekten basit bir şekilde anlaşılacağı üzere txtInput’un Visibility özelliğini chckShow’un IsChecked özelliğine bind yapmış bulunmaktayız. Sonrasında ise ilgili farklı özelliklerin birbirlerine bind olabilmesi ve anlamlandırılabilmesi için hazırda bulunan BooleanToVisibilityConverter yardımı ile Visibility özelliğini sağlamış bulunmaktayız.

Bir sonraki WPF makale serimde ise INotifyPropertyChanged arayüzünün implementasyonu üzerinde duruyor olacağım. Şimdilik sağlıcakla kalın. 🙂

 

Kategori:WPF

Tek Yorum

  1. serdar serdar

    WPF serisi makalelerini bekliyoruz. Çalışmalarında başarılar dilerim

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Bu site, istenmeyenleri azaltmak için Akismet kullanıyor. Yorum verilerinizin nasıl işlendiği hakkında daha fazla bilgi edinin.