I have written a custom control based on a ListBox
. It contains a default ItemTemplate
which shows an image given to the ListBox
by a custom dependency property. The control also contains a default image, which is used when the user doesn't give an image to the dependency property.
This works so far, but now I've found a little problem and I don't know how to fix that.
When I use my custom control in the XAML designer, it first shows the default image. When I set the image's dependency property to an other image, the new image is immediately shown in the XAML designer.
But when I remove the XAML attribute for the new image again, the XAML designer only shows a white rectangle instead of the default image.
I assume it's because with setting the image's dependency property to some value and then removing it I nulled the value. But even when I check for null in the CoerceCallback
and give back the default image when the coerced value is null, doesn't work.
What's the best way to support fallback values for dependency properties?
TestControl.vb
Public Class TestControl
Inherits ListBox
Private Shared _defaultResources As ResourceDictionary
Shared Sub New()
_defaultResources = New ResourceDictionary
_defaultResources.Source = New Uri("...")
End Sub
Public Shared ReadOnly TestProperty As DependencyProperty = DependencyProperty.Register(NameOf(TestControl.Test),
GetType(ImageSource),
GetType(TestControl),
New FrameworkPropertyMetadata(Nothing,
AddressOf TestControl.OnTestChanged,
AddressOf TestControl.OnTestCoerce))
Public Property Test As ImageSource
Get
Return DirectCast(MyBase.GetValue(TestControl.TestProperty), ImageSource)
End Get
Set(value As ImageSource)
MyBase.SetValue(TestControl.TestProperty, value)
End Set
End Property
Private Shared Sub OnTestChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs)
End Sub
Private Shared Function OnTestCoerce(d As DependencyObject, value As Object) As Object
If (value Is Nothing) Then
Return TryCast(_defaultResources.Item("TestImage"), ImageSource)
End If
Return value
End Function
Public Sub New()
Me.Test = TryCast(_defaultResources.Item("TestImage"), ImageSource)
End Sub
End Class
When I use that control like this
<local:TestControl ItemsSource="{Binding Items}" />
every item shows the default image at design time. When I change the XAML to
<local:TestControl ItemsSource="{Binding Items}"
Test="{StaticResource NewImage}" />
every item shows the new item at design time. But when I remove the Test="{StaticResource NewImage}"
again, it doesn't go back to the default image.