Bindings in ToolTip content fail to work after ResourceDictionary reload

95 Views Asked by At

I want to create a ToolTip with a custom content. Because I want to preserve the default behaviour and style of the ToolTip class, I don't want to define its template, but assign a custom content to it instead. I decided to create a ToolTip class descendant with specific dependency properties that will be referenced from the custom content. Here's an example:

Public Class CustomToolTip
    Inherits ToolTip

    Public Shared Property Value1Property As DependencyProperty = DependencyProperty.Register("Value1", GetType(String), GetType(CustomToolTip), New PropertyMetadata(""))

    Public Property Value1 As String
        Get
            Return GetValue(Value1Property)
        End Get
        Set(value As String)
            SetValue(Value1Property, value)
        End Set
    End Property

End Class

I defined the content in a separate resource dictionary file like this:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1">

    <Style x:Key="ToolTipContent" TargetType="local:CustomToolTip">
        <Setter Property="Content">
            <Setter.Value>

                <StackPanel>
                    <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=local:CustomToolTip}, Path=Value1}" />
                </StackPanel>

            </Setter.Value>
        </Setter>
    </Style>

</ResourceDictionary>

The resource dictionary file is referenced from the control that uses the CustomToolTip class, for example:

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525"
    xmlns:local="clr-namespace:WpfApplication1">

    <Window.Resources>
        <ResourceDictionary x:Name="resourceDict">
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="CustomToolTip.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>

    <Canvas>
        <Button x:Name="myButton" Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75">
            <Button.ToolTip>
                <local:CustomToolTip Value1="Test" Style="{DynamicResource ToolTipContent}" />
            </Button.ToolTip>
        </Button>
    </Canvas>
</Window>

This works perfectly fine, but only untill I reload the resource dictionary of the control. I do that in my production app, because it uses custom themes that the user can change at runtime. I reload the dictionary like this (I use merged dictionaries, because in my production app resources are stored in several files):

resourceDict.Clear()

Dim src As New Uri("C:\Users\romico\AppData\Local\Temporary Projects\WpfApplication1\Themes\CustomToolTip.xaml", UriKind.RelativeOrAbsolute)
Dim dict As New ResourceDictionary() With {.Source = src}

resourceDict.MergedDictionaries.Add(dict)

When the dictionary is reloaded, the tool-tip does no longer display any content. Its seems like the binding to Value1 stops working for some reason.

Let me mention that the resource file loaded at runtime differs from the one above, which belongs to the project. The external one declares the 'local' namespace including assembly name:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1;assembly=WpfApplication1">

I will be grateful if you help me solve the problem. Thank you!

1

There are 1 best solutions below

0
On BEST ANSWER

I defined ContentTemplate instead of Content and this fixed the issue. I don't understand why, however (I'm a beginner at WPF). I would be grateful if somebody could explain why this works as opposed to the first approach described above. Thank you!

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1">

    <Style x:Key="ToolTipContent" TargetType="local:CustomToolTip">
        <Setter Property="ContentTemplate">
            <Setter.Value>
                <DataTemplate>

                    <StackPanel>
                        <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=local:CustomToolTip}, Path=Value1}" />
                    </StackPanel>

                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>

</ResourceDictionary>