TwitterFacebookGoogleYouTubeEmailRSS

C# 6.0 – INotifyPropertyChanged – Eine Basis für ein ViewModel

Mit C# 6.0 hat sich viel geändert und vor allem verbessert. So auch die Möglichkeit die Schnittstelle INotifyPropertyChanged einzubinden. Hier bekommt man zwar von der aktuellen ReSharper Version eine schöne Unterstützung, aber wer mehr will, muss noch Hand anlegen. Ich habe in diesem Video das Ganze soweit entwickelt, dass Properties direkt in einem Dictionary gespeichert werden und somit für den Quellcode schlanker aussehen. Trotz einiger Versprecher und Vertipper hier das Video zur Implementierung:


 

Anschließend hier noch der Quellcode zum Video:

class Program
{
    static void Main(string[] args)
    {
        MyViewModel viewModel = new MyViewModel();
        viewModel.Name = "Hello World 123";
        viewModel.Name = "Hello 123";
        viewModel.Name = "World 123";

        Console.ReadLine();
    }
}

public class MyViewModel : ViewModelBase
{
    public string Name
    {
        get { return GetValue<string>(); }
        set { SetValue(value, OnValueSet); }
    }

    private void OnValueSet()
    {
        Console.WriteLine(Name);
    }
}

public abstract class ViewModelBase : INotifyPropertyChanged
{
    private readonly Dictionary<string, object> _propertyValues = new Dictionary<string, object>();

    public event PropertyChangedEventHandler PropertyChanged;

    protected TValue GetValue<TValue>(TValue defaultValue = default(TValue), [CallerMemberName] string propertyName = null)
    {
        string key = $"{typeof (TValue)}::{propertyName}";
        return _propertyValues.ContainsKey(key) ? (TValue) _propertyValues[key] : defaultValue;
    }

    protected void SetValue<TValue>(TValue value, Action callback = null, [CallerMemberName] string propertyName = null)
    {
        string key = $"{typeof(TValue)}::{propertyName}";
        if (_propertyValues.ContainsKey(key))
        {
            if (_propertyValues[key] != null && _propertyValues[key].Equals(value))
                return;

            IComparable comparableValue = value as IComparable;
            IComparable comparableDictionary = _propertyValues[key] as IComparable;
            if (comparableValue != null && comparableDictionary != null)
            {
                if (!Equals(comparableValue, comparableDictionary))
                {
                    _propertyValues[key] = value;
                    OnPropertyChanged(propertyName);
                }
            }
            else
            {
                _propertyValues[key] = value;
                OnPropertyChanged(propertyName);
            }
        }
        else
        {
            _propertyValues.Add(key, value);
            OnPropertyChanged(propertyName);
        }

        callback?.Invoke();
    }

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

2 Gedanke zu “C# 6.0 – INotifyPropertyChanged – Eine Basis für ein ViewModel

  1. Wir setzen bei meinem Arbeitgeber eine ähnliche Basisklasse für die ViewModel-Klassen ein. Alle WPF-Applikationen sollen diese verwenden. Wir distributieren diese via eigenem NuGet-Server. Ich fand die Idee super, auf die einzelnen backing fields verzichten zu können. ich habe den Quellcode ausprobiert, habe aber Probleme bekommen. Zur Laufzeit wird beim Initialisieren eine Exception geworfen. Der aufrufende Thread solle eine STA-Thread sein, da mehrere UI-Komponenten Zugriff hätten. Wie gehe ich hiermit um? Der obige Test erfolgte ja nur aus einer Konsolenapplikation.

    • Es sollte darauf geachtet werden, das View-Aktionen immer vom View-Thread ausgeführt werden. Dies kann man durch Optimierung im Quellcode erzielen. Alternativ kann man versuchen, ob das Attribute „STAThread“ etwas bewirkt bei den betroffenen Methoden. Asynchron zu arbeiten bringt zwar viele Vorteile, aber auch Verantwortung mit sich, damit sauber umzugehen.

Hinterlasse ein Kommentar.

CyberChimps

Cookies erleichtern die Bereitstellung unserer Dienste. Mit der Nutzung unserer Webseite erklären Sie sich damit einverstanden, dass wir Cookies verwenden. Informationen zum Datenschutz

Die Cookie-Einstellungen auf dieser Website sind auf "Cookies zulassen" eingestellt, um das beste Surferlebnis zu ermöglichen. Wenn du diese Website ohne Änderung der Cookie-Einstellungen verwendest oder auf "Akzeptieren" klickst, erklärst du sich damit einverstanden.

Schließen