04 May 2006

The only way DependencyProperties tell that something happend to them seems to be via a binding.

So I implemented an DependencyObject that binds to the the property to be watched.

 

Public Class DependencyProperyChangedHelper(Of T)  
    Inherits DependencyObject

    Public Shared ReadOnly ValueProperty As DependencyProperty = DependencyProperty.Register("Value", GetType(T), GetType(DependencyProperyChangedHelper(Of T)))

    Public Sub New(ByVal d As DependencyObject, ByVal propName As String)  
        Dim bnd As New Binding(propName)  
        bnd.Source = d  
        bnd.Mode = BindingMode.OneWay

        System.Windows.Data.BindingOperations.SetBinding(Me, ValueProperty, bnd)  
    End Sub

    Public Property Value() As T  
        Get  
            Return CType(Me.GetValue(ValueProperty), T)  
        End Get  
        Set(ByVal value As T)  
            Me.SetValue(ValueProperty, value)  
        End Set  
    End Property  
End Class


You can e.g. assign a binding to a TextBox’s TextProperty:

Dim autoCompleteHelper As New DependencyProperyChangedHelper(Of String)(Me.txtNotify, "Text")

The constructor builds a Helper for a String Property on txtNotify named Text.

At the moment the Helper does not do anything else than apply the binding but when you take a closer look at the DependencyProperty.Register overloads you will notify that a PropertyChangedCallback can be supplied:

    Public Shared ReadOnly ValueProperty As DependencyProperty = DependencyProperty.Register("Value", GetType(T), GetType(DependencyProperyChangedHelper(Of T)), New FrameworkPropertyMetadata(New PropertyChangedCallback(AddressOf Value_Changed)))

    Private Shared Sub Value_Changed(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)  
        DirectCast(d, DependencyProperyChangedHelper(Of T)).OnValueChanged(e)  
    End Sub

    ' A Clr Event that is raied whenever the value changes  
    Public Event ValueChanged As DependencyPropertyChangedEventHandler

    ' A Helper Method to raise the event  
    Private Sub OnValueChanged(ByVal e As System.Windows.DependencyPropertyChangedEventArgs)  
        RaiseEvent ValueChanged(Me, e)  
    End Sub

From now on the helper object raises clr events whenever the property it is bound to changes.

Complete Code:

 
Public Class DependencyProperyChangedHelper(Of T)  
    Inherits DependencyObject

    Private mTrackedObject As DependencyObject  
    Public Shared ReadOnly ValueProperty As DependencyProperty = DependencyProperty.Register("Value", GetType(T), GetType(DependencyProperyChangedHelper(Of T)), New FrameworkPropertyMetadata(New PropertyChangedCallback(AddressOf Value_Changed)))

    Public Sub New(ByVal d As DependencyObject, ByVal propName As String)  
        mTrackedObject = d

        Dim bnd As New Binding(propName)  
        bnd.Source = d  
        bnd.Mode = BindingMode.OneWay

        System.Windows.Data.BindingOperations.SetBinding(Me, ValueProperty, bnd)  
    End Sub

    Public ReadOnly Property TrackedObject() As DependencyObject  
        Get  
            Return mTrackedObject  
        End Get  
    End Property

    Public Property Value() As T  
        Get  
            Return CType(Me.GetValue(ValueProperty), T)  
        End Get  
        Set(ByVal value As T)  
            Me.SetValue(ValueProperty, value)  
        End Set  
    End Property

    Private Shared Sub Value_Changed(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)  
        DirectCast(d, DependencyProperyChangedHelper(Of T)).OnValueChanged(e)  
    End Sub

    Private Sub OnValueChanged(ByVal e As System.Windows.DependencyPropertyChangedEventArgs)  
        RaiseEvent ValueChanged(Me, e)  
    End Sub

    Public Event ValueChanged As DependencyPropertyChangedEventHandler  
End Class



blog comments powered by Disqus