C# WPF'de databinding tam olarak nasıl çalışıyor?

Katılım
11 Eylül 2020
Mesajlar
1.857
Çözümler
6
Yer
Almanya
Daha fazla  
Cinsiyet
Erkek
Meslek
König
Merhaba. WPF öğreniyorum. DataBinding kısmında biraz kafam karıştı. Anladığım kadarıyla ModelView sınıfını INotifyPropertyChanged interface inden türetmem ve bu interface ile gelen eventi property set kısmında çalıştırmam gerekiyor. Ama burayı pek kafama oturtamadım. Tam olarak bu evente ne zaman nerde değeri atanıyor? PropertyChangedEventArgs ın parametreleri neye göre veriliyor? Genel olarak DataBinding in işleyişini anlatabilirseniz sevinirim.

C#:
//Binding yaptığımız sınıf
public class Person : INotifyPropertyChanged
{
    private int _Age;
    private string _Name;

    public int Age
    {
        get { return _Age; }
        set
        {
            _Age = value;
            if (PropertyChanged != null)
            {
                PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Age"));
            }
        }
    }
    public string Name
    {
        get { return _Name; }
        set
        {
            if (_Name != value)
            {
                _Name = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Name"));
                }
            }
        }
    }

    public event PropertyChangedEventHandler? PropertyChanged;
}

//MainWindow
public partial class MainWindow : Window
{
    public Person person = new Person()
    {
        Age = 30,
        Name = "Hacı Veli"
    };

    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = person;

    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        MessageBox.Show($"{person.Name} + {person.Age}");
    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        person.Age = 40;
        person.Name = "Mehmet Yılmaz";
    }
}
XML:
<TextBox Name="txt_target"  HorizontalAlignment="Left" Margin="369,104,0,0" TextWrapping="Wrap" Text="{Binding Path=Name,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120"/>
<!--XAML da Binding yaptığım yer. -->
 
Binding genel olarak bir değişkeni bir UI elemanına yansıtmak olabilir bu senaryoda. Tabii binding sadece UI elemanına yapılmaz. Değişik senaryolarda farklı atamalar olabilir.

Interface kısmında ufak bir kavram yanılgınız var. Bir sınıf interface’den türemez, miras almaz. Interface’lerin amacı ‘Bu nesne, şunu yapabilir ve şunlara sahiptir.’ şeklinde bilgilendirmektir. Yani bir nevi bilgisayara bilgi aktarıyorsunuz. Örneğin; siz bir ‘Person’ sınıfından türediniz. Bu sınıf da IPerson interface’ini uygulayabilir. Aslında bu IPerson arabirimi doğrudan yazılmayabilir. IRunnable, ISpeakable, IThinkable gibi interfaceler şeklinde ayrılabilir. Bunun içinde parti şeklinde fonksiyonlar ve bununla alakalı özellikler olabilir. Mesela IRunner’ın içine Run metodunu koymak, Stamina property’si koymak gibi.

Şimdi gelelim asıl sorunuza. Bu bakış açısıyla bakarsak sizin modelinizin ‘Property değiştiğinde bildirebilme’ yeteneği olduğunu okuyabiliyorum. Ama interface’in içinde doğrudan bu yok ama yardımcılar var. Bunu sizin somut sınıfta uygulamanız gerek.

Get dediğiniz zaman property değişmez. Sadece içindeki değeri okursunuz, bu yüzden bu modele bağlı elementlerin güncellenmesine gerek yoktur. Fakat set ettiğinizde değer değişir ve elemanlara da ‘Bu değişti, sen bunun yeni halini göster.’ sinyali gitmesi gerekir. Çünkü bu elemanlar canlı değildir ve CPU’yu fazla tüketmemek için bu değeri sürekli kontrol etmez. Set ederken yazdığınız method ise PropertyChanged statik sınıfındaki metodu çağırarak güncellemeyi sağlar. Buradaki argüman ise hangi property’nin değiştiğini belirtiyor. Yani o prop’u dinleyen elemanlar güncelleniyor. O taraf dotNetin kendi yaptığı bir şey.
 

Technopat Haberler

Geri
Yukarı