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

5

我正在使用MVVM,但是我不想重复造轮子,所以我想找一个开源的视图模型基类。但我找不到。


你希望在这个基类中包含什么? - Deniz Dogan
7个回答

6

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


1
我真的非常希望在提出我的建议之前就知道那个东西了;-) - heads5150

4
我建议MVVM的基本原则非常简单,容易掌握。只需要让类实现INotifyPropertyChanged(基类可以使用标准的OnPropertyChanged(string propertyName)实现),这样就可以拥有所有基本功能。除此之外,还有RelayCommand或类似的实现方式——它只是一个ICommand执行委托中的Execute的一种实现。
总而言之,只需要几行代码就能实现,且代码非常整洁。你还需要什么其他的功能呢?如果需要处理底层BDO(例如DataRowXmlNode或POCO),那么它不应该出现在VM基类中,而应该出现在派生类中。
希望这能对你有所帮助。

1

0

微软Prism。完全访问源代码。学习曲线有点陡峭,但一旦掌握了它,它的表现非常出色。


如果你对面向对象编程和设计模式有很好的了解,并且之前已经使用过依赖注入,那么陡峭的学习曲线就会变得平缓起来。 - Travis Heseman
Prism实际上有ViewModel基类吗?我在几个项目中都使用了Prism,但我从未遇到过这种情况... - BFree
同样的问题:我如何在Prism中访问基本的ViewModel?它在哪个程序集/命名空间中? - user134363
Prism不是一个MVVM框架。 - ecathell
ecathell说得很对,Prism并不是一个MVVM框架。它是一个使你能够创建MMVM设计模式的框架。虽然没有一个基类,但它确实为你提供了创建MVVM设计模式的基础。没有什么万能药方。如果滥用或失去MVC2的纪律性,它就会变成经典的ASP ;-) - heads5150
2
对于现在阅读此内容的任何人,Prism确实有一个名为NotificationObject的视图模型基类,它只具有基本功能(即属性更改通知),但这就是您开始所需的全部。 - Lukazoid

0

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


0

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


-3
这是我的一个例子...它可能对你并没有太大的帮助,因为我想让我的视图模型做的事情和你想让你的视图模型做的事情可能会有所不同...但也许可以给你一个开端。还有关于基类的事情是,如果你把它放在你的核心中...你只需要写一次就可以了...
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

这个问题被标记为C#。 - Mizipzor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接