Noch ein Tipp:
Mit WPF lässt sich sehr gut MVVM nutzen, in dem Zuge ist auch das DataBinding sehr einfach geworden.
Du kannst - kurz gesagt - an alles binden, es funktioniert
Das sieht dann so aus, dass du eine Klasse erstellst, die INotifyPropertyChanged implementieren muss.
Dort kannst du dann Properties deklarieren, an die du binden kannst. So würde ich dir z.B. empfahlen, Commands zu verwenden. Das sind Typen, die ICommand implementieren und damit die Methoden Execute und CanExecute besitzen.
Du kannst auch an Ressourcen binden und dort deine Anzeige-Strings ablegen.
Es gibt auch zwei Klassen, die ich immer in mein Projekt aufnehme:
ViewModelBase und RelayCommand
Nicht unbedingt in der Form, aber ViewModelBase nimmt mir z.B. die Aufgabe ab, immer extra in jeder Property OnPropertyChanged aufzurufen. Das schrumpft dann auf ungefähr folgendes zusammen:
C#-Quelltext
1: 2: 3: 4: 5: 6:
| private string _myName; public string MyName { get { return _myName; } set { base.SetValue(() => MyName, ref _myName, value); } } |
Der erste Parameter ist eine LINQ-Expression, mit der du eine ganze Reihe Informationen über Lambda-Ausdrucke und den dort verwendeten Membern erhalten kannst. Es ist eingeschänkt, es kann nicht alles als Expression benutzt werden, aber zum Abfragen der PropertyInfo und damit dem Namen funktioniert das wunderbar. Expressions sind ein umfangreiches Thema, aber wer sich da einmal zurecht findet, kann damit eine ganze Menge machen. Gerne kann ich auch noch eine Methode posten, die die PropertyInfo abfragt. Ich nutze zur Zeit aber immer die Variante mit dem CallerMemberName, das ich in meinem nächsten Beispiel verwende.
C#-Quelltext
1: 2: 3: 4: 5:
| public string MyName { get { return GetValue(); } set { base.SetValue(value); } } |
Das ist die zweite Variante, die ich gerne nutze, da so die Felder weg fallen, die werden in einem Dictionary in der ViewModelBase gehalten.
Hier habe ich ein kleines Feature vom Compiler genutzt, das wäre die Implementierung von SetValue:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| protected virtual void SetValue<TProperty>(TProperty newValue, [CallerMemberName] string propertyName = "") { var currentValue = _propertyValues[propertyName];
if (!currentValue.Equals(newValue)) { _propertyValues[propertyName] = newValue; OnPropertyChanged(propertyName); } } |
propertyName ist immer der Name des aufrufenden Members - in meinem Fall die MyName-Property.
Commands lassen sich genauso im ViewModel halten - als Property.
Einfach die oben verlinkte RelayCommand-Klasse nutzen (oder ICommand überschreiben) und das Objekt als Property anbieten und daran binden. Wenn CanExecute mal false zurück geben sollte, dann wird das Control ausgegraut, die Methode wird nämlich vom Dispatcher permanent aufgerufen.
Wenn du Commands nutzt, kannst du auch die Events weg lassen und die Klasse hinter dem Window ist komplett leer. Du brauchst dann auch keine Namen den Controls geben.
Dieser Beitrag ist die zweite Hälfte eines Beitrages, den ich auf Wunsch von Christian S. zu Gunsten der Ordnung des ursprünglichen Threads abgetrennt habe. Die erste Hälfte des Beitrages befindet sich hier.