27 Eylül 2023 Çarşamba

C# Yeni Eklenen Property ile Veri Bağlama (Binding)

 Selam. Bu yazıda veri bağlama işlerini deşmeye devam edeceğim. Daha önce basit yollarını gördüğümüz işlemlerin şimdi daha kuralına uygun yapılmasını göreceğiz. Amacımız bir sınıfta Property (özellik) olarak tanımlanan bir değişkeni veri başlama işleminde kullanmak. Adım adım gidelim.

Öncelikle yeni bir WPF .Net masaüstü uygulaması üreterek başlayalım:

Tabi ki Visual Studio ile proje yapıyorum. WPF uygulaması şablonunu seçtikten sonra Sonraki butonuna tıklayarak bir sonraki pencereye geçiyoruz ve orada da projemize bir isim vererek Oluştur butonu ile boş projemizin oluşturulmasını sağlıyoruz. 

Açılan pencere ihtiyacımız için biraz büyük o yüzden boyutlarını direk XAML kod üzerinde 250x300 piksel olarak değiştirelim:

MainWindow.xaml
....
        Title="MainWindow" Height="250" Width="300">
    <Grid>
       
    </Grid>
</Window>



C# Yeni Özellik Değeri (Property) Eklemek

Diyelim amacımızı gerçekleştirmek için Integer (tamsayı) bir değeri tanımlayacağız. Bunu penceremizde bir property olarak tanımlamak için kodda sınıf yapısında tanımlamamız gerekiyor. Proje ürettiğimizde pencere kodumuz otomatik olarak şöyle üretilmiş olmalıdır:

MainWindow.xaml.cs
using System;
using ....

namespace WpfApp3
{
    /// <summary>
    /// MainWindow.xaml etkileşim mantığı
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

MainWindow sınıfımıza Integer1 adında yeni bir özellik (property) ekleyelim.

    public partial class MainWindow : Window
    {
        private int integer1 = 10;
        public int Integer1
        {
            get { return integer1; }
            set { integer1 = value; }
        }
        public MainWindow()
        {
            InitializeComponent();
        }
    }

Şimdi neden sadece public bir değişken ekleyip geçmedik de önce içerde private olarak kullanılan integer1 isimli değişkeni tanımladık, sonra dışarıdan erişilebilen public değişken Integer1 'i tanımladık? Dikkat edersek dışarıdan erişilen Integer1 değeri okunurken aynen içerideki integer1 değeri okunuyor, Integer1 değeri değiştirildiğinde de içerdeki integer1 değeri değişiyor, yani şimdilik ikisi aynı şey. Ancak ilerleyen zamanda dışarıdan erişilen Integer1 özellik değeri değiştiğinde başka gerekli işlemleri yapmak için bu hazırlığı yaptık. Bir küçük ayrıntı daha default olarak özelliğimize 10 değerini verdik, böylece program ilk başlarken değeri 10 olacak. Devam edelim.


İlk Veri Bağlamamızı Bir TextBox ile Yapalım

Şimdi Integer1 özelliğine bir veri bağlaması yapmak için pencereye bir TextBox elemanı ekleyelim. Görsel tasarım penceresi açıkken Araç Kutusu penceresinden TextBox elemanını tutup sürükleyerek pencere içinde boş bir yere bırakalım.

Şimdi bu TextBox elemanının içinde yazan yazı olan Text özelliğini veri bağlama olarak tanımladığımız Integer1 değerine bağlayalım. Bu amacı gerçekleştirmek için TextBox seçiliyken, Özellikler penceresinde Text özelliğini bulalım ve değerin sağ tarafında duran küçük kareyi tıklayalım.

Açılan menüden Veri Bağlama Oluştur... 'u seçelim. Açılan Veri Bağlama seçeneklerinde:

  • Bağlama Türü : ElementName
  • Element Adı : [Window]
  • Yol : Özel 

seçiliyken Yol için özel değer olarak Integer1 yazalım ve Tamam'a tıklayalım.

Ne yaptık? TextBox elemanının Text özelliğini penceremizin sınıf adı olan Window elemanının Integer1 özelliğine bağladık yani Integer1 değerini TextBox üzerinde görmemiz gerekiyor. Hadi deneyelim. Menü tuşlarından yanında yeşil ok işareti olan Başlat tuşuna tıklayalım, bir hata yapmadıysak uygulamamız çalışacak ve şuna benzer bir pencere görünecektir.

Yaşasın! Bir yere vardık. Değeri okuyabiliyoruz. Ama acaba değeri değiştirebiliyor muyuz? Bunu görmek için hadi pencereye bir tane daha TextBox ekleyelim, hatta uğraşmayalım aynısını kopyalayalım. TextBox seçiliyken Ctrl+C ve Ctrl+V basalım ve öncekinin üstünde oluşan 2. TextBox elemanını tutup aşağı çekip yerleştirelim. 

Şimdi çalıştıralım bakalım birinde yaptığımız değişiklik diğerine yansıyor mu?

Malesef! Birinde yaptığımız değişiklik diğerine yansımıyor. Bu durumda değeri değiştiremiyoruz. Ama acaba değer değişiyor da diğerinin haberi mi yok? Bunu test için Integer1 özelliğinin değeri değiştirilince çağrılan set metoduna küçük bir ilave yapalım. 

        public int Integer1
        {
            get { return integer1; }
            set {
                integer1 = value;
                MessageBox.Show("Değer değişti : " + value);
            }
        }

Şimdi çalıştırıp değeri değiştirelim bakalım.

Buradan anlıyoruz ki, değer değişiyor ama diğer kontrolün bundan haberi yok. İşte burada penceremizin temel sınıf yapısına köklü bir ilave yaparak Integer1 ya da başka bir tanımlı özelliği değiştiğinde uygulamadaki diğer elemanlara bildirmesini sağlamamız gerekiyor.


C# Bir Sınıf Özelliğini Veri Bağlamada Kullanmak İçin Yapılması Gerekenler

Öncelikle sınıfımızın özellik değişimlerini uygulama içinde yayınlayabilmesi için INotifyPropertyChanged interface kurallarını içermesi gerekir bu amaçla sınıf tanımının yapıldığı satıra bunu ekliyoruz.

....
namespace WpfApp3
{
    /// <summary>
    /// MainWindow.xaml etkileşim mantığı
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        private int integer1 = 10;
....

Eğer using satırlarında yoksa (ki default olarak yoktur) System.ComponentModel kütüphanesini de pencere kodunda çağırmamız gerekiyor, çünkü bu interface orada tanımlanmış. Bu amaçla da bir using satırı ekleyelim.

using System;
....
using System.ComponentModel;

namespace WpfApp3
....

Gelelim bu interface kuralları için sınıf kodumuza eklememiz gerekenlere. Öncelikle sınıfa bir PropertyChanged adında bir olay ekleriz.

...
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private int integer1 = 10;
        public int Integer1
        {
...

Bu olayı , bir property (özellik) değiştiğinde çağıracağız ki özelliğin değiştiğini uygulamaya bildirelim. Şimdi bu olayı yayınlayan bir sınıf metodu tanımlayalım.

....
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public void NotifyPropertyChanged(string pName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(pName));
            }
        }

        private int integer1 = 10;
....

NotifyPropertyChanged adını verdiğimiz bu metodu bir özelliğin adını parametre girerek çağırdığımızda , uygulamaya o ismi verilen özelliğin değiştiği olayını yayınlar. 

Buraya kadar yaptığımız ilaveler standart olması gereken kodlardı. Şimdi Integer1 özelliğimizin değeri değiştiğinde bu metodu çağırmamız gerekiyor.

....
        private int integer1 = 10;
        public int Integer1
        {
            get { return integer1; }
            set {
                integer1 = value;
                NotifyPropertyChanged("Integer1");
            }
        }
....

Daha sonra ilave edeceğimiz her özelliğin set metodunda bu satırı eklersek uygulamanın o özelliğin değiştiğinden haberi olacaktır. 

Şimdi tekrar çalıştırıp deneyelim.

Artık değer değişince diğeri de değişiyor. Ancak burada can sıkan bir şey daha var, değer ancak kursörü diğer TextBox elemanına geçirince değer değişiyor. Bunun yazdığımız kodlarla bir alakası yok , görsel kodunda TextBox elemanlarının veri bağlamasını yaparken bir nokta eksik kalmış. Tekrar veri bağlama pencerelerini açalım ve aşağıdaki Daha Fazla Ayarlar bölümünde Veri Bağlama Yönü'nü TwoWay ve UpdateSourceTrigger değerini PropertyChanged olarak seçelim. Böylece TextBox içerisinde değişiklik yaptığımız anda diğerine yansıyacaktır. 

Deneyelim ve görelim.

İsterseniz bir de Slider elemanı ekleyelim ve onu da aynı özelliğe bağlayalım, böylece hepsinin aynı değere bağlı değişimini gözleriz. 

Slider elemanı özellikleri şöyle:

  • LargeChenge = 10
  • Maximum = 1000
  • Minimum = 0
  • SmallChange = 1
  • Value = TextBox elemanların Text özelliği aynısı veri bağlama

Çalıştırıp görelim.

İşte bu kadar. 

Aslında bu yazıyı biraz da kendim için hazırladım, her lazım olduğunda  "nasıl yapıyorduk yaa" demekten sıkıldım. Dursun burada, lazım oldukça bakacağım yeri biliyorum artık. Kendinize iyi bakın, güzel günlerde görüşmek üzere kalın sağlıcakla..






Hiç yorum yok:

Yorum Gönder