我最近开始使用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。我只是觉得它有用并不紧凑。我有一个正在进行的应用程序,它已将Properties
与TextBoxes
,Labels
,Buttons
,DataGrids
,... Events
相关联如果你点击一个按钮还没有。因此下面的代码。我发布代码的原因如下:
Private _oShowMsgBox As ICommand
的代码可以缩短吗?从它的外观来看,我需要2 Subs
或Functions
来做我在1中所能做的事情。
Private _oShowMsgBox As ICommand = New RelayCommand(New Action(Of Object)(AddressOf ShowMsgBoxSub),
New Predicate(Of Object)(Function() If(TextboxText = "", False, True)))
是否有必要在文件中包含所有Properties
(Commands
的属性和绑定数据到控件)?我正在处理的应用程序有超过150个控件(TextBox
,Label
,Button
,DataGrid
),因此代码变得非常快,看起来效率非常低
该行下面是我项目中工作代码的快照。把它看作我现在总共的一小部分。
我的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
答案 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中已更改。