views:

574

answers:

1

I trying to use Element Binding in Silverlight 3 to SelectedItem of ComboBox in ToolTipService.ToolTip. This code works:

<ComboBox x:Name="cboSource" DisplayMemberPath="Name" ToolTipService.ToolTip="{Binding ElementName=cboSource, Path=SelectedItem.Name}" Width="180" />

but this code doesn't:

<ComboBox x:Name="cboSource" DisplayMemberPath="Name" Width="180" >
    <ToolTipService.ToolTip>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding ElementName=cboSource, Path=SelectedItem.Code}" Margin="0,0,5,0"/>
            <TextBlock Text="-" Margin="0,0,5,0"/>
            <TextBlock Text="{Binding ElementName=cboSource, Path=SelectedItem.Name}"/>
        </StackPanel>
    </ToolTipService.ToolTip>
</ComboBox>

Name and Code are properties of item in cboSource.ItemsSource. In first code, the Name is correctly displayed in combo's tooltip but in second code tooltip is " - ". Any ideas ?

+1  A: 

Ahh...fun with tooltips.

The ToolTipService is actually "rooted" at the base of the tree (if you have Mole, you can double check to verify this) - hence, it does not get it's DataContext propagated down from parent elements.

I've done hacky things to fix this behavior in the past, but they all boil down to "Code up an attached property that accepts a DataContext and forwards it along to the attached element".

Best of luck - this thing has stung me a couple of times. :)

Ooh, found a link for you: http://www.codeproject.com/Articles/36078/Silverlight-2-0-How-to-use-a-DataBinding-with-the-ToolTipService.aspx

EDIT: Try this out:

        <ComboBox x:Name="cboSource" DisplayMemberPath="Name" Width="180">
        <local:DataBindingTooltip.TooltipDataContext>
            <Binding ElementName="cboSource"/>
        </local:DataBindingTooltip.TooltipDataContext>
        <local:DataBindingTooltip.Tooltip>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding Path=SelectedItem.Code}" Margin="0,0,5,0"/>
                    <TextBlock Text="-" Margin="0,0,5,0"/>
                    <TextBlock Text="{Binding Path=SelectedItem.Name}"/>
                </StackPanel>
        </local:DataBindingTooltip.Tooltip>
    </ComboBox>

With the following class:

    public class DataBindingTooltip
{
    public static readonly DependencyProperty TooltipDataContextProperty =
        DependencyProperty.RegisterAttached(
            "TooltipDataContext",
            typeof (object),
            typeof (DataBindingTooltip),
            null);

    public static readonly DependencyProperty TooltipProperty = 
        DependencyProperty.RegisterAttached(
            "Tooltip", 
            typeof(object), 
            typeof(DataBindingTooltip), 
            new PropertyMetadata(TooltipChanged));

    public static void SetTooltip(DependencyObject d, object value)
    {
        d.SetValue(TooltipProperty, value);
    }
    public static object GetTooltip(DependencyObject d)
    {
        return d.GetValue(TooltipProperty);
    }

    public static void SetTooltipDataContext(DependencyObject d, object value)
    {
        d.SetValue(TooltipDataContextProperty, value);
    }
    public static object GetTooltipDataContext(DependencyObject d)
    {
        return d.GetValue(TooltipDataContextProperty);
    }

    private static void TooltipChanged(DependencyObject sender,
        DependencyPropertyChangedEventArgs e)
    {
        if (sender is FrameworkElement)
        {
            var element = sender as FrameworkElement;
            element.Loaded += ElementLoaded;
        }

    }

    static void ElementLoaded(object sender, RoutedEventArgs e)
    {
        if (sender is FrameworkElement)
        {
            var element = sender as FrameworkElement;
            element.Loaded -= ElementLoaded;

            var tooltip = element.GetValue(TooltipProperty) as DependencyObject;
            if (tooltip != null)
            {
                if (GetTooltipDataContext(element) != null)
                {
                    tooltip.SetValue(FrameworkElement.DataContextProperty,
                                     element.GetValue(TooltipDataContextProperty));
                }
                else
                {
                    tooltip.SetValue(FrameworkElement.DataContextProperty,
                                     element.GetValue(FrameworkElement.DataContextProperty));
                }
            }
            ToolTipService.SetToolTip(element, tooltip);
        }
    }
}
JerKimball
This doesn't solve this problem. There is no binding to DataContext, there is used Element to Element binding.
check my edit - it's still all doable with attached properties
JerKimball