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.
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:
Bu gibi durumlarda binding mekanizması imdadınıza yetişecektir.
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.
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. 🙂
{:tr} Makalenin ilk bölümünde, Software Supply Chain güvenliğinin öneminden ve containerized uygulamaların güvenlik risklerini azaltabilmek…
{: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.…
{:tr}Bildiğimiz gibi bir ürün geliştirirken olabildiğince farklı cloud çözümlerinden faydalanmak, harcanacak zaman ve karmaşıklığın yanı…
{:tr}Bazen bazı senaryolar vardır karmaşıklığını veya eksi yanlarını bildiğimiz halde implemente etmekten kaçamadığımız veya implemente…
{:tr}Bildiğimiz gibi microservice architecture'ına adapte olmanın bir çok artı noktası olduğu gibi, maalesef getirdiği bazı…
{:tr}Bir önceki makale serisinde Dapr projesinden ve faydalarından bahsedip, local ortamda self-hosted mode olarak .NET…
View Comments
WPF serisi makalelerini bekliyoruz. Çalışmalarında başarılar dilerim