Hier geht es zu dem lesenswerten Artikel von Beat Kiener, wo es auch den Quellcode der C#-Version gibt.
Der DependencyPropertyChangedListener ermöglicht es, nach Veränderungen des Werts einer Abhängigkeitseigenschaft zu lauschen und über ein Event hierüber benachrichtigt zu werden. Das ist in vielen Szenarien eine sehr nützliche Sache.
Ich habe den DependencyPropertyChangedListener von Beat Kiener übersetzt nach VB.NET. Denn ich konnte die Klasse in einem VB.NET-Projekt sehr gut brauchen. Beat Kiener war so freundlich und gab mir die Erlaubnis, die von mir übersetzte VB.NET-Version hier in meinem Blog zu veröffentlichen. Vielen Dank nochmal dafür!
Hier also ist der Quellcode der VB.NET-Version (die originalen Kommentare habe ich beibehalten):
DependencyPropertyChangedListener.vb:
Imports System.Windows.Data
Public Class DependencyPropertyChangedListener
#Region "Inner types"
' Helper element to make it possible to use the binding engine
'to get notified when the source element property changes.
Protected Friend Class RelayObject
Inherits DependencyObject
Private Shared _listener As DependencyPropertyChangedListener
Friend Sub New(ByVal listener As DependencyPropertyChangedListener)
_listener = listener
End Sub
Public Shared ReadOnly ValueProperty As DependencyProperty =
DependencyProperty.Register("Value",
GetType(Object),
GetType(RelayObject),
New PropertyMetadata(New Object,
New PropertyChangedCallback(AddressOf OnValueChanged)))
Public Property Value As Object
Get
Return GetValue(ValueProperty)
End Get
Set(ByVal value As Object)
SetValue(ValueProperty, value)
End Set
End Property
Public Shared Sub OnValueChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
Dim oldValue As Object = e.OldValue
Dim newValue As Object = e.NewValue
Dim source As RelayObject = CType(d, RelayObject)
RelayObject.OnValueChanged(oldValue, newValue)
End Sub
Public Shared Sub OnValueChanged(ByVal oldValue As Object, ByVal newValue As Object)
_listener.OnValueChanged(oldValue, newValue)
End Sub
End Class
#End Region
#Region " Events "
' Raises when the dependency property changes.
Public Event ValueChanged As EventHandler(Of DependencyPropertyValueChangedEventArgs)
#End Region
' Holds a reference to the relay object in order that the GC does not collect it
Private Property RelayInstance As RelayObject
Public Shared Function Create(ByVal sourceElement As DependencyObject,
ByVal propertyPath As String) As DependencyPropertyChangedListener
' check input
If sourceElement Is Nothing Then
Throw New ArgumentException("sourceElement")
End If
If String.IsNullOrWhiteSpace(propertyPath) Then
Throw New ArgumentException("propertyPath is empty")
End If
' create listener
Dim listener As DependencyPropertyChangedListener = New DependencyPropertyChangedListener
' setup binding
Dim binding As Binding = New Binding
binding.Source = sourceElement
binding.Mode = BindingMode.OneWay
binding.Path = New PropertyPath(propertyPath)
' create relay object
Dim relay As RelayObject = New RelayObject(listener)
' ...the listener holds a reference to the relay object in order that the GC does not collect it
listener.RelayInstance = relay
' set binding
BindingOperations.SetBinding(relay, RelayObject.ValueProperty, binding)
Return listener
End Function
Public Sub Detach()
If Me.RelayInstance IsNot Nothing Then
' first: reset member to prevent further eventing of ValueChanged event.
Dim temp As RelayObject = Me.RelayInstance
Me.RelayInstance = Nothing
' second: clear the binding -> raises property changed event...
temp.ClearValue(RelayObject.ValueProperty)
End If
End Sub
Private Sub OnValueChanged(ByVal oldValue As Object, ByVal newValue As Object)
' raise event, but only if the listener is not detached.
If Me.RelayInstance IsNot Nothing Then
RaiseEvent ValueChanged(Me, New DependencyPropertyValueChangedEventArgs(oldValue, newValue))
End If
End Sub
End Class
DependencyPropertyValueChangedEventArgs.vb:
Public Class DependencyPropertyValueChangedEventArgs
Inherits EventArgs
Friend Sub New(ByVal oldValue As Object, ByVal newValue As Object)
Me.OldValue = oldValue
Me.NewValue = newValue
End Sub
'/// <summary>
'/// Gets the value of the property before the change.
'/// </summary>
Public Property OldValue As Object
'/// <summary>
'/// Gets the value of the property after the change.
'/// </summary>
Public Property NewValue As Object
End Class
Verwendung in MainPage.xaml.vb:
Partial Public Class MainPage
Inherits UserControl
Private listener As DependencyPropertyChangedListener
Public Sub New()
InitializeComponent()
listener = DependencyPropertyChangedListener.Create(Me.txTest, "Text")
AddHandler listener.ValueChanged,
New EventHandler(Of DependencyPropertyValueChangedEventArgs)(AddressOf listener_ValueChanged)
AddHandler btDetach.Click, AddressOf DetachListener
End Sub
Private Sub listener_ValueChanged(ByVal sender As Object,
ByVal e As DependencyPropertyValueChangedEventArgs)
MessageBox.Show(e.NewValue.ToString)
End Sub
Private Sub DetachListener(ByVal sender As Object, ByVal e As RoutedEventArgs)
If listener IsNot Nothing Then
listener.Detach()
End If
End Sub
End Class
Viel Spass damit.
Keine Kommentare:
Kommentar veröffentlichen