约定和属性
立即下载DevExpress WinForms
MVVM框架处理您的应用程序代码,并用自己的方式解释特定的代码片段,例如如果语法正确,属性可以被认为是可绑定的,这些语法规则称为约定。约定可以避免编写额外的代码,因为框架将“understand”您的期望,并自动生成所需的一切。本文档收集了在构建MVVM应用程序时需要了解的所有MVVM框架约定。
可绑定属性
- 所有公共的虚拟属性都被视为可绑定的。
C#:
public virtual string Test { get; set; }
VB.NET:
Public Overridable Property Test() As String
- 要抑制此类属性的可绑定属性生成,请使用Bindable属性,如下所示:
C#:
[Bindable(false)] public virtual string Test { get; set; }
VB.NET:
<Bindable(False)> Public Overridable Property Test() As String
- 带有支持字段的属性将被框架忽略,您可以使用BindableProperty属性标记这些属性,以便能够将它们用于数据绑定。
C#:
using DevExpress.Mvvm.DataAnnotations; //. . . string test; [BindableProperty] public virtual string Test { get { return test; } set { test = value; } }
VB.NET:
Imports DevExpress.Mvvm.DataAnnotations '. . . Private testField As String <BindableProperty> Public Overridable Property Test() As String Get Return testField End Get Set(ByVal value As String) testField = value End Set End Property
属性依赖
- 属性可以在应用程序运行时更改其值,要跟踪这些更改并对其作出响应,请声明属性依赖项。属性依赖是一种方法,当其相关属性发生更改或即将更改时,该方法会自动执行。要实现此行为,必须调用On<Related_Property_Name>Changing或On<Related_Property_Name>Changed方法。
C#:
public virtual string Test { get; set; } protected void OnTestChanged() { //do something }
VB.NET:
Public Overridable Property Test() As String Protected Sub OnTestChanged() 'do something End Sub
- On…Changed和On. Changed方法也可以有一个参数,在这种情况下参数将分别接收旧的或新的属性值。
C#:
public virtual string Test { get; set; } protected void OnTestChanging(string newValue) { //do something } protected void OnTestChanged(string oldValue) { //do something }
VB.NET:
Public Overridable Property Test() As String Protected Sub OnTestChanging(ByVal newValue As String) 'do something End Sub Protected Sub OnTestChanged(ByVal oldValue As String) 'do something End Sub
- BindableProperty属性还允许使用不同名称的方法。
C#:
[BindableProperty(OnPropertyChangingMethodName = "BeforeChange", OnPropertyChangedMethodName = "AfterChange")] public virtual string Test { get; set; } protected void BeforeChange() { //. . . } protected void AfterChange() { //. . . }
VB.NET:
<BindableProperty(OnPropertyChangingMethodName := "BeforeChange", OnPropertyChangedMethodName := "AfterChange")> Public Overridable Property Test() As String Protected Sub BeforeChange() '. . . End Sub Protected Sub AfterChange() '. . . End Sub
命令行
- 在POCO ViewModels中声明的所有带有零或一个参数的公共void方法都被视为。
C#:
public void DoSomething(object p) { MessageBox.Show(string.Format("The parameter passed to command is {0}.", p)); }
VB.NET:
Public Sub DoSomething(ByVal p As Object) MessageBox.Show(String.Format("The parameter passed to command is {0}.", p)) End Sub
- 您可以用Command(false)属性修饰一个void方法,告诉框架这不是一个有效的MVVM命令。
C#:
using DevExpress.Mvvm.DataAnnotations; [Command(false)] public void DoSomethingInternal(object p) { // TODO }
VB.NET:
Imports DevExpress.Mvvm.DataAnnotations <Command(false)> Public Sub DoSomethingInternal(ByVal p As Object) ' TODO End Sub
- 名称以…Command结尾的方法将引发异常,通过使用Command属性标记这些方法并通过Name参数设置适当的名称,您可以强制框架将这些方法视为有效的命令。
C#:
using DevExpress.Mvvm.DataAnnotations; [Command(Name="DoSomething")] public void DoSomethingCommand(object p) { //do something }
VB.NET:
Imports DevExpress.Mvvm.DataAnnotations <Command(Name := "DoSomething")> Public Sub DoSomethingCommand(ByVal p As Object) 'do something End Sub
- 对于每个命令方法,框架都会生成相应的支持属性,默认情况下此属性会用相关方法加上“Command”后缀命名,您可以使用Command属性的Name参数为这个自动生成的支持属性保留另一个名称。
C#:
[Command(Name = "MyMvvmCommand")] public void DoSomething(object p) { //do something }
VB.NET:
<Command(Name := "MyMvvmCommand")> Public Sub DoSomething(ByVal p As Object) 'do something End Sub
- 命令可以伴随着CanExecute子句—— boolean methods,它只允许在返回true时执行相关命令,这样的方法必须调用Can<Related_Command_Name>。
C#:
//this command will be executed only if "p" equals 4 public void DoSomething(int p) { MessageBox.Show(string.Format("The parameter passed to command is {0}.", p)); } public bool CanDoSomething(int p) { return (2 + 2) == p; }
VB.NET:
'this command will be executed only if "p" equals 4 Public Sub DoSomething(ByVal p As Integer) MessageBox.Show(String.Format("The parameter passed to command is {0}.", p)) End Sub Public Function CanDoSomething(ByVal p As Integer) As Boolean Return (2 + 2) = p End Function
- 具有其他名称的CanExecute方法仍然可以通过使用Command属性的CanExecuteMethodName参数绑定到命令。
C#:
[Command(CanExecuteMethodName = "DoSomethingCriteria")] public void DoSomething(int p) { MessageBox.Show(string.Format("The parameter passed to command is {0}.", p)); } public bool DoSomethingCriteria(int p) { return (2 + 2) == p; }
VB.NET:
<Command(CanExecuteMethodName := "DoSomethingCriteria")> Public Sub DoSomething(ByVal p As Integer) MessageBox.Show(String.Format("The parameter passed to command is {0}.", p)) End Sub Public Function DoSomethingCriteria(ByVal p As Integer) As Boolean Return (2 + 2) = p End Function
当命令刚刚绑定到目标时,首先检查CanExecute子句(以获取目标的初始状态)次CanExecuteChanged事件通知命令的目标关于命令状态更改时,都会重新计算该标准。此事件在底层命令对象级别声明,要从ViewModel级别发送这样的通知,请调用RaiseCanExecuteChanged扩展方法,如下所示。
C#:
//a bindable property public virtual bool IsModified { get; protected set; } //a command public void Save() { //. . . } //a CanExecute condition public bool CanSave() { return IsModified; } //the OnChanged method calls the RaiseCanExecuteChanged method for the "Save" command //this forces the command to update its CanExecute condition public void OnIsModifiedChanged() { this.RaiseCanExecuteChanged(x=>x.Save()); }
VB.NET:
'a bindable property Private privateIsModified As Boolean Public Overridable Property IsModified() As Boolean Get Return privateIsModified End Get Protected Set(ByVal value As Boolean) privateIsModified = value End Set End Property 'a command Public Sub Save() '. . . End Sub 'a CanExecute condition Public Function CanSave() As Boolean Return IsModified End Function 'the OnChanged method calls the RaiseCanExecuteChanged method for the "Save" command 'this forces the command to update its CanExecute condition Public Sub OnIsModifiedChanged() Me.RaiseCanExecuteChanged(Sub(x) x.Save()) End Sub
Services
- 为了解析服务框架会覆盖接口类型的虚拟属性,接口名称必须用…Service结尾。
C#:
public virtual IMyNotificationService MyService { get { throw new NotImplementedException(); } } public virtual IMyNotificationService AnotherService { get { throw new NotImplementedException(); } }
VB.NET:
Public Overridable ReadOnly Property MyService() As IMyNotificationService Get Throw New NotImplementedException() End Get End Property Public Overridable ReadOnly Property AnotherService() As IMyNotificationService Get Throw New NotImplementedException() End Get End Property
- 您还可以使用ServiceProperty属性显式地用其他名称标记服务属性。
C#:
using DevExpress.Mvvm.DataAnnotations; //. . . [ServiceProperty] public virtual IMyNotificationService MyProvider { get { throw new NotImplementedException(); } }
VB.NET:
Imports DevExpress.Mvvm.DataAnnotations '. . . <ServiceProperty> Public Overridable ReadOnly Property MyProvider() As IMyNotificationService Get Throw New NotImplementedException() End Get End Property
- 当框架覆盖一个服务属性时,它会生成相应的GetService<>扩展方法调用,ServiceProperty属性允许您为该方法指定其他参数。
C#:
[ServiceProperty(Key="Service1")] public virtual IMyNotificationService Service { get { throw new NotImplementedException(); } } [ServiceProperty(Key = "Service2")] public virtual IMyNotificationService AnotherService { get { throw new NotImplementedException(); } }
VB.NET:
<ServiceProperty(Key:="Service1")> Public Overridable ReadOnly Property Service() As IMyNotificationService Get Throw New NotImplementedException() End Get End Property <ServiceProperty(Key := "Service2")> Public Overridable ReadOnly Property AnotherService() As IMyNotificationService Get Throw New NotImplementedException() End Get End Property