【问题标题】:MVVM - Is there an open source View Model base class? [closed]MVVM - 是否有开源视图模型基类? [关闭]
【发布时间】:2010-08-05 13:46:50
【问题描述】:

我正在使用 MVVM,而不是重新发明轮子,我想我可以找到一个开源视图模型基类。我找不到一个。

【问题讨论】:

  • 你希望在这个基类中有什么?

标签: c# mvvm open-source


【解决方案1】:

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

【讨论】:

  • 我真的,真的希望在我提出我的建议之前知道那个 ;-)
【解决方案2】:

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

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

希望对您有所帮助。

【讨论】:

    【解决方案3】:

    WPF Application Framework (WAF) 是开源的,包含一个 ViewModel 基类(用于实现 Model-View-ViewModel 模式)。

    【讨论】:

      【解决方案4】:

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

      【讨论】:

      • 如果您对 OO 和设计模式有很好的了解,并且之前使用过依赖注入,那么陡峭的学习曲线就会变得平坦。
      • Prism 实际上有 ViewModel 基类吗?我已经在几个项目中使用 Prism,但我从未真正遇到过....
      • 同样的问题:如何访问 Prism 中的基本 ViewModel?它在哪个程序集/命名空间中?
      • prism 不是 MVVM 框架。
      • 对于现在阅读本文的任何人,Prism 确实有一个名为 NotificationObject 的视图模型基类,它只有基本功能(即属性更改通知),但这就是您真正需要开始的全部。跨度>
      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

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

        【讨论】:

          【解决方案7】:

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

          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# 标记。
          猜你喜欢
          • 2011-09-28
          • 2018-08-02
          • 1970-01-01
          • 1970-01-01
          • 2018-06-12
          • 2014-07-10
          • 1970-01-01
          • 2020-09-11
          • 2021-06-05
          相关资源
          最近更新 更多