Bindable Propety’ler

Merhabalar,

MVVM hakkında bilgi sahibi olduğunuzu varsayarak konuya hızlıca giriyorum (değilseniz öncesinde bu yazıları okuyabilirsiniz). Binding mekanizmasını kullandığımız senaryoları düşünmek için basit bir örneği inceleyelim :

<Entry Text="{Binding Ad}" />	

Burada bir Entry sınıfından örneği (instance) alınmış nesnenin Text özelliğine BindingContext‘den adı “Ad” olan bir özellik bağlanıyor. Bu “Ad” özelliği ise genellikle kendine olan değişiklikleri iletebilmesi için INotifyProperyChanged uygulanmış bir sınıfın içinde bulunur. Zaten MVVM ile uğraşmışsanız buraya kadar hiç bir sıkıntı yok.

Peki ya Text özelliği? Bu özellik bildiğimiz public string Text {get;set;} şeklinde bir özellik olamaz. Çünkü kendisine bir şeyler bağlayabiliyoruz. Bir değişiklik olduğunda yakalıyor ve kendisinde bir değişiklik olduğunda iletebiliyor. Aynı zamanda doğrulama (validation) gibi yetenekleri de var. Bu gibi yeteneklerinden dolayı basit bir arayüz uygulanmış da olamaz. Peki nasıl çözülmüş?

Konunun başlığı zaten çözüm konusunda ipucu veriyor. Burada BindableProperty‘lerden söz ediyoruz. Entrynin Text özelliği bir BindableProperty ve üşenmeden kaynak koduna bakarsak :

 public static public static BindableProperty Create(string propertyName,
 Type returnType, 
 Type declaringType, 
 object defaultValue = null, 
 BindingMode defaultBindingMode = BindingMode.OneWay,
 BindableProperty.ValidateValueDelegate validateValue = null, 
 BindableProperty.BindingPropertyChangedDelegate propertyChanged = null, 
 BindableProperty.BindingPropertyChangingDelegate propertyChanging = null, 
 BindableProperty.CoerceValueDelegate coerceValue = null, 
 BindableProperty.CreateDefaultValueDelegate defaultValueCreator = null)

//...kırpılan satırlar
		public string Text
		{
			get { return (string)GetValue(TextProperty); }
			set { SetValue(TextProperty, value); }
		}

şeklinde tanımlandığını görüyoruz.

İlk satırda BindableProperty nin static oluşturucusuna bu sınıf için böyle bir property (özellik) kaydetmesini söylüyoruz.

Devam eden satırlarda ise alışık olduğumuz bir özellik tanımı mevcut. Bu kısım bu nesneye ait özelliğe dışarıdan erişmek isteyenler için bindable propertye bulaşmadan değer okuyup, yazabilmesini sağlıyor. Burada yer alan GetValue ve SetValue metotları ise BindableObject den gelmekte. Xamarin’de arayüze konu olan bütün sınıflar bu ortak atadan geliyor.

WPF den gelenler için ufak bir bilgilendirme: bu tip özelliklere DependecyProperty adı veriyorduk.

 

Bir BindableProperty’i oluşturmak için kullanacağımız metodun imzası şu şekilde:

public static BindableProperty Create(string propertyName, Type returnType, Type declaringType, object defaultValue = null, BindingMode defaultBindingMode = BindingMode.OneWay, BindableProperty.ValidateValueDelegate validateValue = null, BindableProperty.BindingPropertyChangedDelegate propertyChanged = null, BindableProperty.BindingPropertyChangingDelegate propertyChanging = null, BindableProperty.CoerceValueDelegate coerceValue = null, BindableProperty.CreateDefaultValueDelegate defaultValueCreator = null);		

 

NOT : Bu metotdun bir generic versiyonu bulunsa da kendisi Obsolete olmuş durumda yani ilerleyen zamanlarda kaldırılacağı için kullanmamakta fayda var.

Metodun parametrelerini inceleyelim :

Parametre Açıklama
propertyName Özelliğin dış dünyadaki adı. Kişi sınıfı için “Ad”, “Soyad” gibi düşünebilirsiniz.
returnType Özelliğin dönüş tipi. “Ad” özelliği geriye bir string dönerken, “DoğumTarihi” datetime dönecektir.
declaringType Bu özelliği tanımlayan sınıf. “Kişi” gibi.
defaultValue Özelliğin varsayılan değeri.
defaultBindingMode Bu özelliğin varsayılan bağlama şekli.
validateValue Özellik değeri değiştirildiğinde bunun geçerli bir değer olup olmadığını kontrol edeceğiniz fonksiyon buraya geliyor. Örneğin, “DoğumTarihi” için bugünden sonraki tarihler geçersizdir. Değerin geçerlilik durumuna göre bool bir sonuç dönmeniz yeterlidir.
propertyChanged Özelliğin değerinin değişimi tamamlandıktan sonra işletilecek metot.
propertyChanging Özelliğin değerinin değiştirilme anında işletilecek metot.
coerceValue Özelliğin değerini sınırlandırmak için koyulur. Örneğin “DoğumTarihi ” kısmına bugünden daha büyük bir değer girildiğinde değeri bugün olarak değiştirmek istiyorsanız kullanabilirsiniz. Değerin son halini dönmeniz yeterlidir.
defaultValueCreator Varsayılan değerin verdiğiniz bir fonksiyonun çalıştırılması sonucunda elde edilmesini sağlar. Örneğin “KayıtTarihi” şeklinde bir özellik için bu parametreye bugünün tarihini dönen bir fonksiyon verebilirsiniz. b=> DateTime.Now

 

Örnek kullanım:

    public partial class OzelView : Entry
    {
        public static readonly BindableProperty AdProperty = BindableProperty.Create("Ad", typeof(string), typeof(OzelView));

    }

 

Bu özelliğin dışarıdan klasik yöntemle erişilebilmesi için :

        public string Ad
        {
            get { return GetValue(AdProperty) as string; }
            set { SetValue(AdProperty, value); }
        }

 

Böylece bu özel Entry sınıfımın Binding yeteneklerine sahip bir Ad özelliği oldu. Bu entryimi daha sonra şu şekilde kullanabilirim:

  <userControls:OzelEntry Ad="{Binding Ad}"  />

 

 

Burdan sonrası ihtiyaçlara göre değişiyor. Çeşitli ihtiyaçlara göre örnekleri paylaşıyor olacağım.

Konuyla ilgili olarak resmi dokümana https://developer.xamarin.com/guides/xamarin-forms/xaml/bindable-properties/ adresinden ulaşabilirsiniz.

Cihan Yakar

Yorum Gönder