MVVM - 是否有开源视图模型基类?

发布于 2024-09-13 12:10:29 字数 1536 浏览 6 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

月牙弯弯 2024-09-20 12:10:29

MVVM Light 也是一个很好的解决方案,并且它有一个非常容易找到的基类:-)

MVVM Light is also a good solution, and it has a really easy to find base class :-)

娇纵 2024-09-20 12:10:29

我认为 MVVM 的基本原理非常简单,因此重新发明轮子会更容易。您需要的所有基本功能是该类实现 INotifyPropertyChanged(基类可以具有 OnPropertyChanged(string propertyName) 的标准样式实现)。除此之外,还有 RelayCommand 或类似的 - 只是一个在 Execute 中执行委托的 ICommand 实现。

总而言之,只有几行代码,而且非常整洁。您还在寻找什么其他功能?如果它要处理底层 BDO(例如 DataRowXmlNode 或 POCO),那么它实际上不应该位于 VM 基类中,而应该位于派生类中。

希望有帮助。

I would suggest that the basic principles of MVVM are so simple that it would be easier to reinvent the wheel. All the basic functionality you need is for the class to implement INotifyPropertyChanged (the base class could have the standard-style implementation of OnPropertyChanged(string propertyName)). Beyond that there's the RelayCommand or similar - just an ICommand implementation that executes a delegate in Execute.

All-in-all, just a few lines of code, and it keeps it very neat. What other functionality are you looking for? If it's to deal with the underlying BDO (say a DataRow, XmlNode or POCO) then it shouldn't really be in the VM base class, but a derived class.

Hope that helps.

残疾 2024-09-20 12:10:29

WPF 应用程序框架 (WAF) 是开源的,包含 ViewModel 基类 (用于实现模型-视图-视图模型模式)。

The WPF Application Framework (WAF) is open source and contains a ViewModel base class (for implementing the Model-View-ViewModel pattern).

陌路终见情 2024-09-20 12:10:29

微软Prism。完全访问源代码。学习曲线有点陡峭,但一旦掌握了它,它就会非常有效。

Microsoft Prism. Full access to the source code. A bit of a steep learning curve but once you get a handle of it, it works really well.

落叶缤纷 2024-09-20 12:10:29

查看 Nikhail Kothari 的博客,了解他的 SilverlightFX 库,它是一个开源 MVVM,您可能会发现有用。

Check out Nikhail Kothari's blog for his SilverlightFX library, its an open source MVVM u might find useful.

半葬歌 2024-09-20 12:10:29

SoapBox Core 是一个开源 (LGPL) MVVM(和 MEF)框架,用于构建可扩展的 MVVM 应用程序。类层次结构包括一个基本 ViewModel 类(以及与此相关的接口)。

SoapBox Core is an open source (LGPL) MVVM (and MEF) framework for building extensible MVVM applications. The class hierarchy includes a base ViewModel class (and interface for that matter).

清醇 2024-09-20 12:10:29

这是我的一个例子......它不会真正帮助你,因为我想要我的视图模型做的事情会与你想要你的视图模型做的事情不同......但也许它会给你一个开始。基类的问题是,如果你把它放在你的核心中......你只需要写一次......

Imports System.ComponentModel
Imports System.Windows
Imports Microsoft.Practices.Composite.Events
Imports WavelengthIS.Core.Services
Imports WavelengthIS.Core.Bases
Imports Ocean.OceanFramework.CommonDialog
Imports WavelengthIS.WPF.Events

Namespace WavelengthIS.WPF.Bases

    Public MustInherit Class ViewModelBase
        Inherits WavelengthIS.Core.Bases.Base
        Implements IDisposable, INotifyPropertyChanged

#Region " Declarations "
        Private _headerinfo As String
        Private _backgroundworker As BackgroundWorker

#End Region

#Region " Properties "
        Public Property HeaderInfo() As String
            Get
                Return _headerinfo

            End Get
            Set(ByVal value As String)
                If Not (value Is String.Empty) Or Not (IsNothing(value)) Then
                    _headerinfo = value
                End If

            End Set
        End Property

        Protected ReadOnly Property BackGroundWorker() As BackgroundWorker
            Get
                If _backgroundworker Is Nothing Then
                    _backgroundworker = New BackgroundWorker
                End If
                Return _backgroundworker
            End Get
        End Property

        Private _isdirty As Boolean = False
        Protected Property IsDirty As Boolean
            Get
                Return _isdirty
            End Get
            Set(ByVal value As Boolean)
                If Not Equals(value, _isdirty) Then
                    _isdirty = value
                    If _isdirty = True Then
                        DisableNavigation()
                    Else
                        EnableNavigation()
                    End If
                End If
            End Set
        End Property

        ''' <summary>
        ''' not a databinding property. No need for onpropertychanged notifications
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Protected Property IsLoading As Boolean = False

        Private _haschanges As Boolean
        Public Property HasChanges As Boolean
            Get
                Return _haschanges
            End Get
            Set(ByVal value As Boolean)
                If Not Equals(value, _haschanges) Then
                    _haschanges = value
                    If value = True Then
                        GetEvent(Of Events.DisableCloseButtonEvent).Publish(True)
                    End If
                    OnPropertyChanged("HasChanges")
                End If
            End Set
        End Property


#End Region

#Region " Dialogs "
        'This is not in Bases because it would cause circular references.

        ''' <summary>
        ''' Gets the IDialogService registered with the ServiceContainer.
        ''' use ShowMessage or ShowException in child code.
        ''' </summary>
        Private ReadOnly Property Dialog() As Dialog.IDialogService
            Get
                Return GetService(Of Dialog.IDialogService)()
            End Get
        End Property

        Protected Function ShowMessage(ByVal message As String, ByVal caption As String, ByVal button As Dialog.DialogButton, ByVal image As Dialog.DialogImage) As Ocean.OceanFramework.CommonDialog.CustomDialogResult
            GetEvent(Of Events.DialogShowingEvent).Publish(True)
            Dim rslt As CustomDialogResult = Dialog.ShowMessage(message, caption, button, image)
            GetEvent(Of Events.DialogShowingEvent).Publish(False)
            Return rslt
        End Function

        Protected Sub ShowException(ByVal message As String, Optional ByVal expandedMessage As String = Nothing, Optional ByVal image As Dialog.DialogImage = Core.Services.Dialog.DialogImage.Error)
            GetEvent(Of Events.DialogShowingEvent).Publish(True)
            Dialog.ShowException(message, expandedMessage, image)
            GetEvent(Of Events.DialogShowingEvent).Publish(False)

        End Sub
#End Region

#Region " Wait States "

        Private ReadOnly Property Wait As WavelengthIS.Core.Services.IWaitingService
            Get
                Return GetService(Of IWaitingService)()
            End Get
        End Property

        Protected Sub BeginWait()
            GetEvent(Of Events.DisplayWaitingControlEvent).Publish(True)
        End Sub

        Protected Sub EndWait()
            GetEvent(Of Events.DisplayWaitingControlEvent).Publish(False)
        End Sub
#End Region

#Region " Events "
        Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged


#End Region

#Region " Constructor "
        Public Sub New()
            _backgroundworker = New BackgroundWorker
            AddHandler _backgroundworker.DoWork, AddressOf BackGroundWorker_DoWork
            AddHandler _backgroundworker.RunWorkerCompleted, AddressOf BackGroundWorker_RunWorkerCompleted

        End Sub

#End Region

#Region " IDisposable Support "

        Private disposedValue As Boolean = False        ' To detect redundant calls

        ' IDisposable
        Protected Overridable Sub Dispose(ByVal disposing As Boolean)
            If Not Me.disposedValue Then
                If disposing Then
                    ' TODO: free other state (managed objects).
                End If

                ' TODO: free your own state (unmanaged objects).
                ' TODO: set large fields to null.
            End If
            Me.disposedValue = True
        End Sub
        ' This code added by Visual Basic to correctly implement the disposable pattern.
        Public Sub Dispose() Implements IDisposable.Dispose
            ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub
#End Region

#Region " Debugging Helpers "
        <Conditional("DEBUG")> _
        Public Sub VerifyPropertyName(ByVal propertyName As String)

            'If you raise PropertyChanged and do not specify a property name,
            'all properties on the object are considered to be changed by the binding system.
            If String.IsNullOrEmpty(propertyName) Then
                Return
            End If

            ' Verify that the property name matches a real,  
            ' public, instance property on this object.
            'If TypeDescriptor.GetProperties(Me)(propertyName) Is Nothing Then
            '    Dim msg As String = "Invalid property name: " & propertyName
            '    Throw New Exception(msg)
            'End If
        End Sub

        Private _ThrowOnInvalidPropertyName As Boolean
        Protected Property ThrowOnInvalidPropertyName() As Boolean
            Get
                Return _ThrowOnInvalidPropertyName
            End Get
            Private Set(ByVal value As Boolean)
                _ThrowOnInvalidPropertyName = value
            End Set
        End Property




#End Region

#Region " INotifyProperty Changed Method "


        Protected Overridable Sub OnPropertyChanged(ByVal strPropertyName As String)
            Me.VerifyPropertyName(strPropertyName)

            If Me.PropertyChangedEvent IsNot Nothing Then
                RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs(strPropertyName))
            End If


        End Sub

        Private Function QualifyString(ByVal str As String) As Boolean



            Return True

        End Function

        Protected Overridable Sub OnPropertyChanged(ByVal strPropertyName As String, ByVal IsPrimaryProperty As Boolean)
            Me.OnPropertyChanged(strPropertyName)

        End Sub

#End Region

#Region " Navigation Events "

        Protected Sub EnableNavigation()
            'Keep from firing multiple onPropertyChanged events
            If HasChanges = True Then
                HasChanges = False
            End If

            GetEvent(Of DisableNavigationEvent).Publish(False)

        End Sub

        Protected Sub DisableNavigation()
            'Keep from firing multiple onPropertyChanged events
            If HasChanges = False Then
                HasChanges = True
            End If

            GetEvent(Of DisableNavigationEvent).Publish(True)

        End Sub

#End Region
    End Class

End Namespace

Here is an example of mine...it wont really help you, because want I want my viewmodels to do will be different then what you want your viewmodels to do...but maybe it will give you a start. And the thing with the base class is if you stick it in your Core...you only have to write it once...

Imports System.ComponentModel
Imports System.Windows
Imports Microsoft.Practices.Composite.Events
Imports WavelengthIS.Core.Services
Imports WavelengthIS.Core.Bases
Imports Ocean.OceanFramework.CommonDialog
Imports WavelengthIS.WPF.Events

Namespace WavelengthIS.WPF.Bases

    Public MustInherit Class ViewModelBase
        Inherits WavelengthIS.Core.Bases.Base
        Implements IDisposable, INotifyPropertyChanged

#Region " Declarations "
        Private _headerinfo As String
        Private _backgroundworker As BackgroundWorker

#End Region

#Region " Properties "
        Public Property HeaderInfo() As String
            Get
                Return _headerinfo

            End Get
            Set(ByVal value As String)
                If Not (value Is String.Empty) Or Not (IsNothing(value)) Then
                    _headerinfo = value
                End If

            End Set
        End Property

        Protected ReadOnly Property BackGroundWorker() As BackgroundWorker
            Get
                If _backgroundworker Is Nothing Then
                    _backgroundworker = New BackgroundWorker
                End If
                Return _backgroundworker
            End Get
        End Property

        Private _isdirty As Boolean = False
        Protected Property IsDirty As Boolean
            Get
                Return _isdirty
            End Get
            Set(ByVal value As Boolean)
                If Not Equals(value, _isdirty) Then
                    _isdirty = value
                    If _isdirty = True Then
                        DisableNavigation()
                    Else
                        EnableNavigation()
                    End If
                End If
            End Set
        End Property

        ''' <summary>
        ''' not a databinding property. No need for onpropertychanged notifications
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Protected Property IsLoading As Boolean = False

        Private _haschanges As Boolean
        Public Property HasChanges As Boolean
            Get
                Return _haschanges
            End Get
            Set(ByVal value As Boolean)
                If Not Equals(value, _haschanges) Then
                    _haschanges = value
                    If value = True Then
                        GetEvent(Of Events.DisableCloseButtonEvent).Publish(True)
                    End If
                    OnPropertyChanged("HasChanges")
                End If
            End Set
        End Property


#End Region

#Region " Dialogs "
        'This is not in Bases because it would cause circular references.

        ''' <summary>
        ''' Gets the IDialogService registered with the ServiceContainer.
        ''' use ShowMessage or ShowException in child code.
        ''' </summary>
        Private ReadOnly Property Dialog() As Dialog.IDialogService
            Get
                Return GetService(Of Dialog.IDialogService)()
            End Get
        End Property

        Protected Function ShowMessage(ByVal message As String, ByVal caption As String, ByVal button As Dialog.DialogButton, ByVal image As Dialog.DialogImage) As Ocean.OceanFramework.CommonDialog.CustomDialogResult
            GetEvent(Of Events.DialogShowingEvent).Publish(True)
            Dim rslt As CustomDialogResult = Dialog.ShowMessage(message, caption, button, image)
            GetEvent(Of Events.DialogShowingEvent).Publish(False)
            Return rslt
        End Function

        Protected Sub ShowException(ByVal message As String, Optional ByVal expandedMessage As String = Nothing, Optional ByVal image As Dialog.DialogImage = Core.Services.Dialog.DialogImage.Error)
            GetEvent(Of Events.DialogShowingEvent).Publish(True)
            Dialog.ShowException(message, expandedMessage, image)
            GetEvent(Of Events.DialogShowingEvent).Publish(False)

        End Sub
#End Region

#Region " Wait States "

        Private ReadOnly Property Wait As WavelengthIS.Core.Services.IWaitingService
            Get
                Return GetService(Of IWaitingService)()
            End Get
        End Property

        Protected Sub BeginWait()
            GetEvent(Of Events.DisplayWaitingControlEvent).Publish(True)
        End Sub

        Protected Sub EndWait()
            GetEvent(Of Events.DisplayWaitingControlEvent).Publish(False)
        End Sub
#End Region

#Region " Events "
        Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged


#End Region

#Region " Constructor "
        Public Sub New()
            _backgroundworker = New BackgroundWorker
            AddHandler _backgroundworker.DoWork, AddressOf BackGroundWorker_DoWork
            AddHandler _backgroundworker.RunWorkerCompleted, AddressOf BackGroundWorker_RunWorkerCompleted

        End Sub

#End Region

#Region " IDisposable Support "

        Private disposedValue As Boolean = False        ' To detect redundant calls

        ' IDisposable
        Protected Overridable Sub Dispose(ByVal disposing As Boolean)
            If Not Me.disposedValue Then
                If disposing Then
                    ' TODO: free other state (managed objects).
                End If

                ' TODO: free your own state (unmanaged objects).
                ' TODO: set large fields to null.
            End If
            Me.disposedValue = True
        End Sub
        ' This code added by Visual Basic to correctly implement the disposable pattern.
        Public Sub Dispose() Implements IDisposable.Dispose
            ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub
#End Region

#Region " Debugging Helpers "
        <Conditional("DEBUG")> _
        Public Sub VerifyPropertyName(ByVal propertyName As String)

            'If you raise PropertyChanged and do not specify a property name,
            'all properties on the object are considered to be changed by the binding system.
            If String.IsNullOrEmpty(propertyName) Then
                Return
            End If

            ' Verify that the property name matches a real,  
            ' public, instance property on this object.
            'If TypeDescriptor.GetProperties(Me)(propertyName) Is Nothing Then
            '    Dim msg As String = "Invalid property name: " & propertyName
            '    Throw New Exception(msg)
            'End If
        End Sub

        Private _ThrowOnInvalidPropertyName As Boolean
        Protected Property ThrowOnInvalidPropertyName() As Boolean
            Get
                Return _ThrowOnInvalidPropertyName
            End Get
            Private Set(ByVal value As Boolean)
                _ThrowOnInvalidPropertyName = value
            End Set
        End Property




#End Region

#Region " INotifyProperty Changed Method "


        Protected Overridable Sub OnPropertyChanged(ByVal strPropertyName As String)
            Me.VerifyPropertyName(strPropertyName)

            If Me.PropertyChangedEvent IsNot Nothing Then
                RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs(strPropertyName))
            End If


        End Sub

        Private Function QualifyString(ByVal str As String) As Boolean



            Return True

        End Function

        Protected Overridable Sub OnPropertyChanged(ByVal strPropertyName As String, ByVal IsPrimaryProperty As Boolean)
            Me.OnPropertyChanged(strPropertyName)

        End Sub

#End Region

#Region " Navigation Events "

        Protected Sub EnableNavigation()
            'Keep from firing multiple onPropertyChanged events
            If HasChanges = True Then
                HasChanges = False
            End If

            GetEvent(Of DisableNavigationEvent).Publish(False)

        End Sub

        Protected Sub DisableNavigation()
            'Keep from firing multiple onPropertyChanged events
            If HasChanges = False Then
                HasChanges = True
            End If

            GetEvent(Of DisableNavigationEvent).Publish(True)

        End Sub

#End Region
    End Class

End Namespace
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文