你需要MVVM中的所有属性吗?

时间:2014-03-10 10:18:53

标签: wpf vb.net mvvm properties

我最近开始使用MVVM,并在http://www.dotmaniac.net/wpf-karl-shifletts-relaycommand/http://www.codeproject.com/Articles/126249/MVVM-Pattern-in-WPF-A-Simple-Tutorial-for-Absolute的帮助下找出了如何使用Commands。我成功地完成了一项简单的测试。

下面是我刚才提到的这些资源中的代码。所以要澄清一下,我发布的代码是IS WORKING。我只是觉得它有用并不紧凑。我有一个正在进行的应用程序,它已将PropertiesTextBoxesLabelsButtonsDataGrids,... Events相关联如果你点击一个按钮还没有。因此下面的代码。我发布代码的原因如下:

  1. Private _oShowMsgBox As ICommand的代码可以缩短吗?从它的外观来看,我需要2 SubsFunctions来做我在1中所能做的事情。

    Private _oShowMsgBox As ICommand = New RelayCommand(New Action(Of Object)(AddressOf ShowMsgBoxSub), 
                                                        New Predicate(Of Object)(Function() If(TextboxText = "", False, True)))
    
  2. 是否有必要在文件中包含所有PropertiesCommands的属性和绑定数据到控件)?我正在处理的应用程序有超过150个控件(TextBoxLabelButtonDataGrid),因此代码变得非常快,看起来效率非常低

  3. 该行下面是我项目中工作代码的快照。把它看作我现在总共的一小部分。


    我的xaml:

    <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:MVVM_Test" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="MainWindow" Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <local:ViewModel x:Key="ViewModelDataSource" d:IsDataSource="True" />
        </Window.Resources>
        <Grid DataContext="{Binding Source={StaticResource ViewModelDataSource}}">
            <Button Content="{Binding TextboxText}" Command="{Binding ShowMsgBox}"/>
            <TextBox Text="{Binding TextboxText, UpdateSourceTrigger=PropertyChanged}" />
        </Grid>
    </Window>
    

    我第一次成功地在我的代码后面没有代码。

    这是我提出的RelayCommand:

    Public Class RelayCommand
    Implements ICommand
    
    #Region "Fields"
    Private ReadOnly _execute As Action(Of Object)
    Private ReadOnly _canExecute As Predicate(Of Object)
    #End Region
    
    #Region "Constructors"
    Public Sub New(ByVal execute As Action(Of Object))
        Me.New(execute, Nothing)
    End Sub
    
    Public Sub New(ByVal execute As Action(Of Object), ByVal canExecute As Predicate(Of Object))
    
        If execute Is Nothing Then
            Throw New ArgumentNullException("execute")
        End If
    
        _execute = execute
        _canExecute = canExecute
    
    End Sub
    
    #End Region
    
    #Region "ICommand Members"
    
    Public Function CanExecute(parameter As Object) As Boolean Implements ICommand.CanExecute
        Return If(_canExecute Is Nothing, True, _canExecute(parameter))
    End Function
    
    
    Public Custom Event CanExecuteChanged As EventHandler Implements ICommand.CanExecuteChanged
    
        AddHandler(ByVal value As EventHandler)
            AddHandler CommandManager.RequerySuggested, value
        End AddHandler
    
        RemoveHandler(ByVal value As EventHandler)
            RemoveHandler CommandManager.RequerySuggested, value
        End RemoveHandler
    
        RaiseEvent(ByVal sender As System.Object, ByVal e As System.EventArgs)
    
        End RaiseEvent
    
    End Event
    Public Sub Execute(parameter As Object) Implements ICommand.Execute
        _execute(parameter)
    End Sub
    
    #End Region
    
    End Class
    

    然后在我的ViewModel中我有这个:

    Imports System.ComponentModel
    Imports System.Runtime.CompilerServices
    
    Public Class ViewModel
    Implements INotifyPropertyChanged
    
    Private _sText As String
    Public Property TextboxText As String
        Get
            Return _sText
        End Get
        Set(ByVal value As String)
            _sText = value
            RaisePropertyChanged()
        End Set
    End Property
    
    Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged
    
    Protected Sub RaisePropertyChanged(<CallerMemberName()> Optional ByVal propertyName As String = Nothing)
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
    End Sub
    
    Private _oShowMsgBox As ICommand = New RelayCommand(New Action(Of Object)(AddressOf ShowMsgBoxSub), New Predicate(Of Object)(Function() If(TextboxText = "", False, True)))
    Public Property ShowMsgBox As ICommand
        Get
            Return _oShowMsgBox
        End Get
        Set(ByVal value As ICommand)
            _oShowMsgBox = value
        End Set
    End Property
    
    Public Sub ShowMsgBoxSub()
        MessageBox.Show(TextboxText)
    End Sub
    
    End Class
    

1 个答案:

答案 0 :(得分:1)

对于命令,我怀疑你的情况是readonly,你应该能够使用VB.Net的auto property功能:

Public Property ShowMsgBox _
 As New RelayCommand( _
   New Action(Of Object)(AddressOf ShowMsgBoxSub), _
   New Predicate(Of Object)(Function() If(TextboxText = "", False, True)))

对于更改的可绑定属性,您需要使用verbose属性语法,并通过在实现INotifyPropertyChanged的视图模型类上触发PropertyChanged事件来表示该属性在setter中已更改。