6
Vote

TabControl Issue

description

Hello, first of all, awesome product.
 
I have a tabbed application. The problem is that tabs will unload children from the visual tree, and thus the tooltip will be unregistered. when the tab is reactivated, the tooltip must once again be registered, which is not done in tooltipservice. Heres a short fully working example to demonstrate the problem with tabs.
 
1) Create a new Silverlight 4 project. Add references to System.Windows.Controls & Silverlight.Controls.Tooltips.
 
Paste this in your MainPage.xaml:
<UserControl x:Class="Repoduce_Bug_D_02315.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
xmlns:CustomToolTips="clr-namespace:Silverlight.Controls.ToolTips;assembly=Silverlight.Controls.ToolTips"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
 
<Grid x:Name="LayoutRoot" Background="White">
  <Controls:TabControl>
    <Controls:TabItem Header="Tab1">
      <TextBlock Text="My textblock which has a tooltip">
        <CustomToolTips:ToolTipService.ToolTip>
          <CustomToolTips:ToolTip DisplayTime="Forever"
                                  InitialDelay="00:00:00">
            <TextBlock Text="My ToolTip contents"/>
          </CustomToolTips:ToolTip>
        </CustomToolTips:ToolTipService.ToolTip>
      </TextBlock>
    </Controls:TabItem>
    <Controls:TabItem Header="Tab2">
      <TextBlock Text="My textblock in tab 2 which also has a tooltip">
        <CustomToolTips:ToolTipService.ToolTip>
          <CustomToolTips:ToolTip DisplayTime="Forever"
                                  InitialDelay="00:00:00">
            <TextBlock Text="My ToolTip contents in tab 2"/>
          </CustomToolTips:ToolTip>
        </CustomToolTips:ToolTipService.ToolTip>
      </TextBlock>
    </Controls:TabItem>
  </Controls:TabControl>
</Grid>
</UserControl>
 
 
How to reproduce: hold the mouse over the first text that appears. Works as expected. Change to tab2. hold the mouse over the text that appears. Works as expected. Change back to tab1. Now, the tooltip doesnt show up anymore. Change to tab2 and same thing here - the tooltip doesnt show up. The tooltip will not come back until the control is reinstanciated.
 
I posted a fix for this in patches.

comments

sbryfcz wrote Nov 15, 2011 at 5:06 PM

I love the possibilities with this but I also have a tabbed application and I have the same issue.

Where do I go for patches? Sorry, i'm new to this and can't find it anywhere. Please help! This is a great product but I HAVE to have this fixed and I'd rather not repeat work if its already done. Thanks,

wrote Dec 5, 2011 at 5:04 PM

wrote Jan 16, 2012 at 10:10 PM

AngryPixel wrote Mar 1, 2012 at 5:43 PM

I have the same issue, when will the fix for this be available?

wrote May 18, 2012 at 9:01 AM

Tewr wrote Aug 16, 2012 at 12:01 PM

Well this is kind of late and I'm sure you found it by now if you were desperete enough. Patches are on Sourcecode/patches: http://tooltipservice.codeplex.com/SourceControl/list/patches

gopalakrishnach wrote Oct 4, 2012 at 10:19 PM

I had the same issue and I fixed using below code int ToolTipService.cs

private static void FrameworkElementReloaded(object sender, RoutedEventArgs e)
   {
     var owner = sender as FrameworkElement;
     if (owner == null)
     {
       throw new ArgumentException("Expected a FrameworkElement", "sender");
     }
     // Remove the loaded event, this may be fired again when virtualizing etc
     owner.Loaded -= FrameworkElementReloaded;
     // re-register tooltip
     RegisterToolTip(owner, owner.GetValue(ToolTipObjectProperty));
   }

private static void UnregisterToolTip(UIElement owner)
    {
        if (owner.GetValue(ToolTipObjectProperty) == null)
        {
            return;
        }

        var frameworkElement = owner as FrameworkElement;
         //if (owner is FrameworkElement)
          if (frameworkElement != null)
           {
            //((FrameworkElement)owner).Unloaded -= FrameworkElementUnloaded;
             frameworkElement.Unloaded -= FrameworkElementUnloaded;
            frameworkElement.Loaded += FrameworkElementReloaded;
            }
        owner.MouseEnter -= OnElementMouseEnter;
        owner.MouseLeave -= OnElementMouseLeave;

        var toolTip = (ToolTip)owner.GetValue(ToolTipObjectProperty);
        if (toolTip.IsOpen)
        {
            toolTip.IsOpen = false;
        }
        toolTip.SetOwner(null);
       // owner.ClearValue(ToolTipObjectProperty);

        if (elementsAndToolTips.ContainsKey(owner))
        {
            elementsAndToolTips.Remove(owner);
        }
    }

wrote Feb 14, 2013 at 7:02 PM