在VB.NET中(没有引用第三方库),我发现我写了很多以下代码:
Private _prop as String = "test"
Public Property Prop As String
Get
Return _prop
End Get
Set(value As String)
_prop = value
NotifyPropertyChanged()
End Set
'(add more properties here...)
Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged
Protected Overridable Sub NotifyPropertyChanged(<CallerMemberName> Optional propertyName As String = "")
If PropertyChangedEvent IsNot Nothing Then
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End If
End Sub
我希望能够做的是:
Public ObservableProperty Prop As String = "test"
并让ObservableProperty成为我定义的构造所有样板文件的构造。
我知道如果我不想让它成为Observable,我可以使用相同的模式(Public Property NonObsProp As String = "test"
),那么是否也可以自动观察它们?
答案 0 :(得分:1)
在Knockout.js的启发下,减少INPC属性样板的一种可能方法是定义一个可观察的值类型。
Imports System.ComponentModel
Public Class ObservableValue(Of T)
Implements INotifyPropertyChanging, INotifyPropertyChanged
Public Event PropertyChanging As PropertyChangingEventHandler Implements INotifyPropertyChanging.PropertyChanging
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Private Shared ReadOnly __changing As PropertyChangingEventArgs = New PropertyChangingEventArgs("Value")
Private Shared ReadOnly __changed As PropertyChangedEventArgs = New PropertyChangedEventArgs("Value")
Public Sub New()
End Sub
Public Sub New(initialValue As T)
_value = initialValue
End Sub
Private _value As T
Public Property Value As T
Get
Return _value
End Get
Set(newValue As T)
If Not EqualityComparer(Of T).Default.Equals(_value, newValue) Then
RaiseValueChanging()
_value = newValue
RaiseValueChanged()
End If
End Set
End Property
Public Sub RaiseValueChanging()
RaiseEvent PropertyChanging(Me, __changing)
End Sub
Public Sub RaiseValueChanged()
RaiseEvent PropertyChanged(Me, __changed)
End Sub
Public Overrides Function ToString() As String
Return If(_value IsNot Nothing, _value.ToString(), String.Empty)
End Function
Public Shared Widening Operator CType(value As T) As ObservableValue(Of T)
Return New ObservableValue(Of T)(value)
End Operator
End Class
然后可以使用它来定义属性 - 该类不一定需要实现INotifyPropertyChanged
,除非出于某些其他原因需要这样做。
Public Class MyViewModel
Public ReadOnly Property Prop1 As ObservableValue(Of String) = "A"
Public ReadOnly Property Prop2 As ObservableValue(Of Boolean) = False
End Class
然后,您需要记住在获取/设置值时.Value
属性(ReadOnly
有帮助,并且可能有更优雅的方式来公开基础值),例如,在WPF绑定中:
vm.Prop1.Value = "NewValue"
<TextBlock Text="{Binding Prop1.Value}"/>
我还没有充分利用这种模式来发现缺点......甚至是典型的INPC模式的优势。
答案 1 :(得分:0)
@sstan的评论指出了我正确的方向。这不是一个完美的答案,但它是我现在最接近的答案。
基本上,这是here引用的方式,它建议创建一个调用SetProperty
的{{1}}方法,减少样板代码。
类似的东西:
NotifyPropertyChanged