Categories: WPF

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.

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.

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. 🙂

 

Gökhan Gökalp

View Comments

Recent Posts

Event-Driven Architecture’larda Conditional Claim-Check Pattern’ı ile Event Boyut Sınırlarının Üstesinden Gelmek

{:en}In today’s technological age, we typically build our application solutions on event-driven architecture in order…

2 ay ago

Containerized Uygulamaların Supply Chain’ini Güvence Altına Alarak Güvenlik Risklerini Azaltma (Güvenlik Taraması, SBOM’lar, Artifact’lerin İmzalanması ve Doğrulanması) – Bölüm 1

{:tr}Bildiğimiz gibi modern yazılım geliştirme ortamında containerization'ın benimsenmesi, uygulamaların oluşturulma ve dağıtılma şekillerini oldukça değiştirdi.…

9 ay ago

Identity & Access Management İşlemlerini Azure AD B2C ile .NET Ortamında Gerçekleştirmek

{:tr}Bildiğimiz gibi bir ürün geliştirirken olabildiğince farklı cloud çözümlerinden faydalanmak, harcanacak zaman ve karmaşıklığın yanı…

1 yıl ago

Azure Service Bus Kullanarak Microservice’lerde Event’ler Nasıl Sıralanır (FIFO Consumers)

{:tr}Bazen bazı senaryolar vardır karmaşıklığını veya eksi yanlarını bildiğimiz halde implemente etmekten kaçamadığımız veya implemente…

2 yıl ago

.NET Microservice’lerinde Outbox Pattern’ı ile Eventual Consistency için Atomicity Sağlama

{:tr}Bildiğimiz gibi microservice architecture'ına adapte olmanın bir çok artı noktası olduğu gibi, maalesef getirdiği bazı…

2 yıl ago