是否可以覆盖Parameter关键字,或为可观察属性创建新的关键字?

时间:2016-07-27 15:34:20

标签: .net vb.net properties observable

在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"),那么是否也可以自动观察它们?

2 个答案:

答案 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