Tipp-Upload: VB.NET 0430: INotifyPropertyChanged-Basisklasse für MVVM (WPF)
von GoaZwerg
Über den Tipp
Dieser Tippvorschlag wird übernommen.
Der Vorschlag ist in den folgenden Kategorien zu finden:
- Sonstiges
Dem Tippvorschlag wurden folgende Schlüsselwörter zugeordnet:
MVVM, WPF, VB.NET
Der Vorschlag wurde erstellt am: 24.02.2012 00:16.
Die letzte Aktualisierung erfolgte am 26.09.2017 20:11.
Beschreibung
Wer mit dem M-V-VM Pattern in WPF arbeitet wird sicherlich das Problem kennen, dass man bei INotifyPropertyChanges den Propertynamen stets im Klartext angeben muss, was - bei Unachtsamkeit - zu Debugging-Orgien führen kann. Mit diesem Tipp möchte ich eine kleine Lösung zeigen, wie man sowas mit LINQ elegant umgehen kann und stets Typsicher bleibt, ohne gleich ein M-V-VM Framework verwenden zu müssen.
Im Beispiel zeige ich die Verwendung meiner Basisklasse nur im ViewModel, aber in den Models und BusinessModels lässt sich das natürlich genau so anwenden. Die Beispielanwendung merkt sich einfach mal die Fenstergröße und Position im MVVM-Pattern unter Verwendung dieser Basisklasse, ohne je eine Property namentlich benennen zu müssen. Zudem zeige ich hier, wie man die GetName() Methode verwendet, um ebenso typsicher auf Events reagieren kann, ohne Strings.
Die Anwendung ist recht einfach, jedes ViewModel, Model oder BusinessModel erbt von der Basisklasse:
Inherits ViewModelsBase
Anschließend lässt sich in jeder Property im Setter dies String-los ausführen:
OnPropertyChanged(Function() <NAME>, value)
Value wird hier für das Trace oder Debug-Logging gleich mit übergeben.
Und die GetName() Methode ermöglicht auch bei EventHandlern eine String-lose Behandlung, hier ein Beispiel:
Private Sub OnSizeChanged(sender As Object, e As PropertyChangedEventArgs) Handles Me.PropertyChanged
If e.PropertyName = GetName(Function() Width) Or e.PropertyName = GetName(Function() Height) Then
My.Settings.MainWindowSize = New System.Drawing.Size(_Width, _Height)
End If
End Sub
Schwierigkeitsgrad |
Verwendete API-Aufrufe: |
Download: |
' Dieser Source stammt von http://www.activevb.de ' und kann frei verwendet werden. Für eventuelle Schäden ' wird nicht gehaftet. ' Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum. ' Ansonsten viel Spaß und Erfolg mit diesem Source! ' ' Beachten Sie, das vom Designer generierter Code hier ausgeblendet wird. ' In den Zip-Dateien ist er jedoch zu finden. ' --------- Anfang Projektdatei MVVM_Demo_App.vbproj --------- ' -------------- Anfang Datei MyWpfExtension.vb -------------- #If _MyType <> "Empty" Then Namespace My ''' <summary> ''' Modul zum Definieren der im My-Namespace für WPF verfügbaren Eigenschaften ''' </summary> ''' <remarks></remarks> <Global.Microsoft.VisualBasic.HideModuleName()> Module MyWpfExtension Private s_Computer As New ThreadSafeObjectProvider(Of _ Global.Microsoft.VisualBasic.Devices.Computer) Private s_User As New ThreadSafeObjectProvider(Of _ Global.Microsoft.VisualBasic.ApplicationServices.User) Private s_Windows As New ThreadSafeObjectProvider(Of MyWindows) Private s_Log As New ThreadSafeObjectProvider(Of Global.Microsoft.VisualBasic.Logging.Log) ''' <summary> ''' Gibt das Anwendungsobjekt für die ausgeführte Anwendung zurück. ''' </summary> <Global.System.Diagnostics.CodeAnalysis.SuppressMessageAttribute( _ "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")> Friend ReadOnly _ Property Application() As Application Get Return CType(Global.System.Windows.Application.Current, Application) End Get End Property ''' <summary> ''' Gibt Informationen über den Hostcomputer zurück. ''' </summary> <Global.System.Diagnostics.CodeAnalysis.SuppressMessageAttribute( _ "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")> Friend ReadOnly _ Property Computer() As Global.Microsoft.VisualBasic.Devices.Computer Get Return s_Computer.GetInstance() End Get End Property ''' <summary> ''' Gibt Informationen über den aktuellen Benutzer zurück. Wenn Sie die Anwendung mit den aktuellen Windows- ''' Anmeldeinformationen ausführen möchten, rufen Sie My.User.InitializeWithWindowsUser() auf. ''' </summary> <Global.System.Diagnostics.CodeAnalysis.SuppressMessageAttribute( _ "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")> Friend ReadOnly _ Property User() As Global.Microsoft.VisualBasic.ApplicationServices.User Get Return s_User.GetInstance() End Get End Property ''' <summary> ''' Gibt das Anwendungsprotokoll zurück. Die Listener können in der Konfigurationsdatei der Anwendung konfiguriert werden. ''' </summary> <Global.System.Diagnostics.CodeAnalysis.SuppressMessageAttribute( _ "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")> Friend ReadOnly _ Property Log() As Global.Microsoft.VisualBasic.Logging.Log Get Return s_Log.GetInstance() End Get End Property ''' <summary> ''' Gibt die im Projekt definierte Windows-Auflistung zurück. ''' </summary> <Global.System.Diagnostics.CodeAnalysis.SuppressMessageAttribute( _ "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")> Friend ReadOnly _ Property Windows() As MyWindows <Global.System.Diagnostics.DebuggerHidden()> Get Return s_Windows.GetInstance() End Get End Property <Global.System.ComponentModel.EditorBrowsableAttribute( _ Global.System.ComponentModel.EditorBrowsableState.Never)> _ <Global.Microsoft.VisualBasic.MyGroupCollection( "System.Windows.Window", _ "Create__Instance__", "Dispose__Instance__", _ "My.MyWpfExtenstionModule.Windows")> Friend NotInheritable Class MyWindows <Global.System.Diagnostics.DebuggerHidden()> Private Shared Function _ Create__Instance__(Of T As {New, Global.System.Windows.Window})(ByVal _ Instance As T) As T If Instance Is Nothing Then If s_WindowBeingCreated IsNot Nothing Then If s_WindowBeingCreated.ContainsKey(GetType(T)) = True Then Throw New Global.System.InvalidOperationException("The window " & _ "cannot be accessed via My.Windows from the Window " & _ "constructor.") End If Else s_WindowBeingCreated = New Global.System.Collections.Hashtable() End If s_WindowBeingCreated.Add(GetType(T), Nothing) Return New T() s_WindowBeingCreated.Remove(GetType(T)) Else Return Instance End If End Function <Global.System.Diagnostics.CodeAnalysis.SuppressMessageAttribute( _ "Microsoft.Performance", "CA1822:MarkMembersAsStatic")> _ <Global.System.Diagnostics.DebuggerHidden()> Private Sub Dispose__Instance__( _ Of T As Global.System.Windows.Window)(ByRef instance As T) instance = Nothing End Sub <Global.System.Diagnostics.DebuggerHidden()> _ <Global.System.ComponentModel.EditorBrowsableAttribute( _ Global.System.ComponentModel.EditorBrowsableState.Never)> Public Sub New() MyBase.New() End Sub <Global.System.ThreadStatic()> Private Shared s_WindowBeingCreated As _ Global.System.Collections.Hashtable <Global.System.ComponentModel.EditorBrowsable( _ Global.System.ComponentModel.EditorBrowsableState.Never)> Public Overrides _ Function Equals(ByVal o As Object) As Boolean Return MyBase.Equals(o) End Function <Global.System.ComponentModel.EditorBrowsable( _ Global.System.ComponentModel.EditorBrowsableState.Never)> Public Overrides _ Function GetHashCode() As Integer Return MyBase.GetHashCode End Function <Global.System.Diagnostics.CodeAnalysis.SuppressMessageAttribute( _ "Microsoft.Performance", "CA1822:MarkMembersAsStatic")> _ <Global.System.ComponentModel.EditorBrowsable( _ Global.System.ComponentModel.EditorBrowsableState.Never)> Friend Overloads _ Function [GetType]() As Global.System.Type Return GetType(MyWindows) End Function <Global.System.ComponentModel.EditorBrowsable( _ Global.System.ComponentModel.EditorBrowsableState.Never)> Public Overrides _ Function ToString() As String Return MyBase.ToString End Function End Class End Module End Namespace Partial Class Application Inherits Global.System.Windows.Application <Global.System.Diagnostics.CodeAnalysis.SuppressMessageAttribute( _ "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")> _ <Global.System.Diagnostics.CodeAnalysis.SuppressMessageAttribute( _ "Microsoft.Performance", "CA1822:MarkMembersAsStatic")> Friend ReadOnly Property _ Info() As Global.Microsoft.VisualBasic.ApplicationServices.AssemblyInfo <Global.System.Diagnostics.DebuggerHidden()> Get Return New Global.Microsoft.VisualBasic.ApplicationServices.AssemblyInfo( _ Global.System.Reflection.Assembly.GetExecutingAssembly()) End Get End Property End Class #End If ' --------------- Ende Datei MyWpfExtension.vb --------------- ' ---------- Ende Projektdatei MVVM_Demo_App.vbproj ----------
Diskussion
Diese Funktion ermöglicht es, Fragen, die die Veröffentlichung des Tipps betreffen, zu klären, oder Anregungen und Verbesserungsvorschläge einzubringen. Nach der Veröffentlichung des Tipps werden diese Beiträge nicht weiter verlinkt. Allgemeine Fragen zum Inhalt sollten daher hier nicht geklärt werden.
Um eine Diskussion eröffnen zu können, müssen sie angemeldet sein.