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

Securing the Supply Chain of Containerized Applications to Reduce Security Risks (Security Scanning, SBOMs, Signing&Verifying Artifacts) – Part 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.…

1 month ago

Delegating Identity & Access Management to Azure AD B2C and Integrating with .NET

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

5 months ago

How to Order Events in Microservices by Using Azure Service Bus (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…

1 year ago

Providing Atomicity for Eventual Consistency with Outbox Pattern in .NET Microservices

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

1 year ago

Building Microservices by Using Dapr and .NET with Minimum Effort – 02 (Azure Container Apps)

{:tr}Bir önceki makale serisinde Dapr projesinden ve faydalarından bahsedip, local ortamda self-hosted mode olarak .NET…

1 year ago

Some Awesome News of .NET 7

{:tr}Bildiğimiz gibi .NET Conf 2022, 8-10 kasım arasında gerçekleşti. Konferans sırasında ise .NET 7 ve…

1 year ago