Feb 07

Silverlight3小技巧:从Binding获取值

BlendSDK里面的交互模式很好用,不过交互的类全部从DependencyObject继承,没办法绑定很不方便。于是就弄了这个类出来:

   1: Public NotInheritable Class BindingEvaluator(Of T)

   2:     Private Shared ReadOnly DummyProperty As DependencyProperty = DependencyProperty.RegisterAttached("Dummy", GetType(T), GetType(BindingEvaluator(Of T)), New PropertyMetadata(DependencyProperty.UnsetValue))

   3:  

   4:     Private Shared Function GetDummy(ByVal element As DependencyObject) As T

   5:         ' IMPORTANT: To maintain parity between setting a property in XAML and procedural code, do not touch the getter and setter inside this dependency property!

   6:         If (element Is Nothing) Then

   7:             Throw New ArgumentNullException("element")

   8:         End If

   9:         Return CType(element.GetValue(BindingEvaluator(Of T).DummyProperty), T)

  10:     End Function

  11:     Private Shared Sub SetDummy(ByVal element As DependencyObject, ByVal value As T)

  12:         ' IMPORTANT: To maintain parity between setting a property in XAML and procedural code, do not touch the getter and setter inside this dependency property!

  13:         If (element Is Nothing) Then

  14:             Throw New ArgumentNullException("element")

  15:         End If

  16:         element.SetValue(BindingEvaluator(Of T).DummyProperty, value)

  17:     End Sub

  18:  

  19:     Public Shared Function GetValue(ByVal source As FrameworkElement, ByVal binding As Binding) As T

  20:         Dim value = GetRawValue(source, binding)

  21:         If value Is DependencyProperty.UnsetValue Then

  22:             Return Nothing

  23:         End If

  24:         Return CType(value, T)

  25:     End Function

  26:  

  27:     Public Shared Function GetRawValue(ByVal source As FrameworkElement, ByVal binding As Binding) As Object

  28:         If source Is Nothing Then

  29:             Throw New ArgumentNullException("source", "source is nothing.")

  30:         End If

  31:         If binding Is Nothing Then

  32:             Throw New ArgumentNullException("binding", "binding is nothing.")

  33:         End If

  34:         Dim newBinding As New Binding() With { _

  35:             .BindsDirectlyToSource = binding.BindsDirectlyToSource, _

  36:             .Converter = binding.Converter, _

  37:             .ConverterCulture = binding.ConverterCulture, _

  38:             .ConverterParameter = binding.ConverterParameter, _

  39:             .Mode = BindingMode.OneTime, _

  40:             .Path = binding.Path _

  41:         }

  42:         If Not String.IsNullOrEmpty(binding.ElementName) Then

  43:             newBinding.ElementName = binding.ElementName

  44:         ElseIf binding.RelativeSource IsNot Nothing Then

  45:             newBinding.RelativeSource = binding.RelativeSource

  46:         ElseIf binding.Source IsNot Nothing Then

  47:             newBinding.Source = binding.Source

  48:         Else

  49:             '    newBinding.Source = source.DataContext

  50:         End If

  51:  

  52:         source.SetBinding(DummyProperty, newBinding)

  53:         Dim value = GetDummy(source)

  54:         source.ClearValue(DummyProperty)

  55:  

  56:         Return value

  57:     End Function

  58:  

  59:     Private Sub New()

  60:  

  61:     End Sub

  62: End Class

SL4就要支持DependencyObject绑定了,期待。。。