none
Opening a ToolTip programmatically

    Question

  • Hi all,

    how can I open a ToolTip attached to a Control programmatically?


    Regards Uwe
    Monday, January 24, 2011 12:37 AM

Answers

  • Luckily for you I am a WPF expert.  If I understand you correctly you want the tooltip to stay visible as you type.  Is this correct?  If so, what you need is the StaysOpen property.

      <Grid>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto" />
          <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
    
        <TextBox x:Name="_textBox">
          <TextBox.ToolTip>
            <ToolTip>
              <TextBlock Text="This is a tooltip" />
            </ToolTip>
          </TextBox.ToolTip>
        </TextBox>
        
        <StackPanel Grid.Row="1" Orientation="Horizontal">
          <Button Click="OpenButton_Click">Show Tooltip</Button>
          <Button Click="CloseButton_Click">Close Tooltip</Button>
        </StackPanel>
    
      </Grid>
    

    Code:

        private void OpenButton_Click(object sender, RoutedEventArgs e)
        {
          ((ToolTip)_textBox.ToolTip).StaysOpen = true;
          ((ToolTip)_textBox.ToolTip).IsOpen = true;
        }
    
        private void CloseButton_Click(object sender, RoutedEventArgs e)
        {
          ((ToolTip)_textBox.ToolTip).StaysOpen = false;
          ((ToolTip)_textBox.ToolTip).IsOpen = false;
        }
    

    This basic example works perfectly.  I click the Show button and start typing, the tooltip stays visible.  It will only dissapear when I click the close button.

    • Marked as answer by UwePfalz Tuesday, January 25, 2011 6:40 PM
    • Unmarked as answer by UwePfalz Tuesday, January 25, 2011 6:41 PM
    • Marked as answer by UwePfalz Tuesday, January 25, 2011 6:53 PM
    Monday, January 24, 2011 11:23 PM
  • I don't think you have a bug in your .NET.  The tooltip just isn't meant to be used the way you are using it.  You may eventually get it close, but I still think an adorner is a better solution.  Good luck.
    • Marked as answer by UwePfalz Friday, January 28, 2011 5:35 PM
    Wednesday, January 26, 2011 9:14 PM
  • Hi Brian,

    with help from you and Masuadur I could luckily implement the programmatically opening ToolTip with automatic closing after a "Showtime". These are the basics of the solution (C#):

    1. I create a "Stopped" DispatcherTimer with an interval calculated from "ShowDuration" on the Control that needs it and store the Timer in the Controls Tag property.
    2. The DispatcherTimer is wrapped in a class that adds a property to store a reference to the Control in the timer so that I can find the ToolTip in the Tick-Event
    3. When requested the ToolTip is opened by IsOpen property and the Timer is started
    4. When the Timer fires "Tick" the ToolTip is closed and the timer is stopped.

    This works flawlessly w/o any interference to the other functions of the ToolTip. I did in depth testing and it works great. No undocumented or MS internal interfaces are used. It can be used with XAML defined or programmatically attached ToolTips. I have not tested it yet for ToolTips generated from a string.

    I also tried your proposal to use Adorners for a while. When I analysed the Adorner layer with Visual Tree Viewer I discovered that a ToolTip seem to used similar visual handling. So I stopped that approach because the standard ToolTip functionality is better integrated in the solution described above.

    Thank you again for your help.

    If somebody is interested in the code, please let me know. I'll then post it here.


    Regards Uwe
    • Marked as answer by UwePfalz Friday, January 28, 2011 5:36 PM
    Friday, January 28, 2011 5:35 PM

All replies

  • Hi

    try this.

    xaml

    --------------------



    <Button Content="Button" Height="23" HorizontalAlignment="Left"Name="button1">

                <Button.ToolTip>

                    <ToolTip Content="this is a button"></ToolTip>

                </Button.ToolTip>

            </Button>

    ---------------------

    c#

    ---------------------

    ((ToolTip) button1.ToolTip).IsOpen = true;





    ------------------------------------------------

    Best of luck

    Md. Masudur Rahman

    Md. Masudur Rahman
    • Proposed as answer by Parvez_Ansari Monday, January 24, 2011 12:17 PM
    • Unproposed as answer by UwePfalz Monday, January 24, 2011 3:51 PM
    Monday, January 24, 2011 6:46 AM
  • Hello Masadur,

    I tried my very best, but your proposal does not open the ToolTip. I think that we must look in the direction of raising a RoutedEvent against the ToolTip. But I have no idea what this could be.


    Regards Uwe
    Monday, January 24, 2011 3:51 PM
  • Hi,

    In which event you are trying to display the tooltip? I have tested it and work fine.  

    http://www.codeproject.com/Articles/36930/Tooltip-service-and-tooltip-facility-of-WPF.aspx

     


    Md. Masudur Rahman
    Monday, January 24, 2011 3:55 PM
  • Hi Masudur,

    very nice pages on Tooltips. My compliments to this great job. I did these studies myself and know how difficult that matter is.

    In my case here, I'm looking for a solution to open a ToolTip that has been already created and assigned either in XAML or C# by programming and not by hovering the mouse over the attachee (e.g. the TextBox or the Button). I have understood your message above that you proposed to open the ToolTip by sending true to the IsOpen property of the ToolTip. This does not work here, I'm afraid, and I have not found an example for this in the samples in your site.

    The Event approach I mentioned has the following design idea:

    Any of the MouseOver and other hover events is captured by the base Control and either converted to an event signaling the ToolTip to open itself or the ToolTip is created and shown by the base Control. So basically we would simulate a MouseOver.


    Regards Uwe
    Monday, January 24, 2011 6:06 PM
  • Hi Brian,

    I have some experience with adorner. This would be a possible alternate solution.

    The requirement I have to implement is a little more "ToolTip"-based because the programmed Open of the ToolTip should occur with different texts in the ToolTip as an explanation of the content of the TextBox immediately when the Text is entered and the user tabs away from the TextBox. After then the ToolTip should close after its defined time and appear again on request be hovering with the mouse over the TextBox later on.

    Everything works well with the ToolTip except the programmed Open. There seems to be no method or property that triggers an open. I tried IsOpen and some other.

    So my idea is to raise the event against the TextBox that leads to opening of the ToolTip. I have nothing found on this in MSDN yet. The most promising candidate seems to be the ToolTipOpening event.

    I'm sure that the WPF experts will have better ideas.


    Regards Uwe
    Monday, January 24, 2011 11:03 PM
  • Luckily for you I am a WPF expert.  If I understand you correctly you want the tooltip to stay visible as you type.  Is this correct?  If so, what you need is the StaysOpen property.

      <Grid>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto" />
          <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
    
        <TextBox x:Name="_textBox">
          <TextBox.ToolTip>
            <ToolTip>
              <TextBlock Text="This is a tooltip" />
            </ToolTip>
          </TextBox.ToolTip>
        </TextBox>
        
        <StackPanel Grid.Row="1" Orientation="Horizontal">
          <Button Click="OpenButton_Click">Show Tooltip</Button>
          <Button Click="CloseButton_Click">Close Tooltip</Button>
        </StackPanel>
    
      </Grid>
    

    Code:

        private void OpenButton_Click(object sender, RoutedEventArgs e)
        {
          ((ToolTip)_textBox.ToolTip).StaysOpen = true;
          ((ToolTip)_textBox.ToolTip).IsOpen = true;
        }
    
        private void CloseButton_Click(object sender, RoutedEventArgs e)
        {
          ((ToolTip)_textBox.ToolTip).StaysOpen = false;
          ((ToolTip)_textBox.ToolTip).IsOpen = false;
        }
    

    This basic example works perfectly.  I click the Show button and start typing, the tooltip stays visible.  It will only dissapear when I click the close button.

    • Marked as answer by UwePfalz Tuesday, January 25, 2011 6:40 PM
    • Unmarked as answer by UwePfalz Tuesday, January 25, 2011 6:41 PM
    • Marked as answer by UwePfalz Tuesday, January 25, 2011 6:53 PM
    Monday, January 24, 2011 11:23 PM
  • Hi Brian,

    good to hear that you can help with best WPF expertise. So your example was very helpful.

    Your solution does not fully covered my requirements described in my posting above (... After then the ToolTip should close after its defined time and appear again on request be hovering with the mouse over the TextBox later on .), but it showed how to open a ToolTip by my own code. Very helpfull, indeed.

    I had to adjust things a little:

    1. Because the default Placement is "Mouse" the ToolTip appeared at the button clicked, not attached to the TextBox where it belongs to.
    2. Clearing StaysOpen in the IsOpen = false clause lead to a "NotSupported" exception when hovering over the TextBox after closing the ToolTip manually.

    To cure the placement problem, I added a Placement Property in XAML. After this the isOpen clause no more worked. The reason turned out to be the need for setting PlacementTarget Property when other placements than Mouse are specified. BTW: This was the reason for my original question: I was using a Placement Property of Bottom from the beginning and so IsOpen did not work.

    So my final setup in C# (XAML as show by Brian) is as follows:

    private void OpenButton_Click( object sender, RoutedEventArgs e ) {
      ((ToolTip)_textBox.ToolTip).Placement = PlacementMode.Bottom;
      ((ToolTip)_textBox.ToolTip).PlacementTarget = _textBox;
      ((ToolTip)_textBox.ToolTip).IsOpen = true;
      }
    
    private void CloseButton_Click( object sender, RoutedEventArgs e ) {
      ((ToolTip)_textBox.ToolTip).IsOpen = false;
      }
    

    Setting the Placement should be better done in XAML because there it is set when instantiating the ToolTip.

    So everything is up to my needs except one important topic: The Tooltip should close automatically after the ShowDuration time (see above). I tried setting this with ToolTipService in XAML and in C# as an attached property: No success.

    So this is my new problem : How can I activate the TollTip closing after the ShowDuration time when it has been opened by the IsOpen pattern?


    Regards Uwe
    • Edited by UwePfalz Tuesday, January 25, 2011 6:51 PM Typos
    Tuesday, January 25, 2011 6:40 PM
  • Using the exmaple I provided; I get the desired effect by setting the TooltipService.ShowDuration property.  I am sure you will find that the tooltip will not always behave as you expect it to when trying to manipulate it's behavior programattically.  You may need the help of a timer and hide the tooltip manually.  As I mentioned earlier, I believe an adorner would be a better solution to your problem.  Good luck.

    Tuesday, January 25, 2011 7:02 PM
  • Hello Brian,

    I tried my very best to reproduce what you wrote, but the ToolTip opened by IsOpen refused to disappear after the ShowDurationTime. Could you please have a look at the code below to guide me where the difference is?

    XAML
    ------
    
    <Window x:Class="PamToolTip.ToolTipWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
        Title="MainWindow" Height="350" Width="525">
      <Grid>
      <Grid.RowDefinitions>
       <RowDefinition Height="Auto" />
       <RowDefinition Height="Auto" />
      </Grid.RowDefinitions>
    
      <TextBox x:Name="_textBox" Margin="20"
           ToolTipService.ShowDuration="1000" 
           ToolTipService.Placement="Bottom">
       <TextBox.ToolTip >
        <ToolTip>
         <TextBlock Text="This is a tooltip" />
        </ToolTip>
       </TextBox.ToolTip>
      </TextBox>
    
      <StackPanel Grid.Row="1" Orientation="Horizontal" Margin="20" HorizontalAlignment="Stretch">
       <Button Height="40" Margin="0 0 10 0" Click="OpenButton_Click">Show Tooltip</Button>
       <Button Height="40" Margin="0 0 10 0" Click="CloseButton_Click">Close Tooltip</Button>
      </StackPanel>
    
     </Grid>
    </Window>
    
    Code behind
    --------------
    namespace PamToolTip {
      public partial class ToolTipWindow : Window {
    
       public ToolTipWindow() {
         InitializeComponent();
         }
    
       private void OpenButton_Click( object sender, RoutedEventArgs e ) {
         TextBox textBox = this._textBox;
         ToolTip toolTip = (ToolTip)textBox.ToolTip;
         ((ToolTip)textBox.ToolTip).PlacementTarget = textBox;
         ((ToolTip)textBox.ToolTip).IsOpen = true;
         }
    
       private void CloseButton_Click( object sender, RoutedEventArgs e ) {
         ((ToolTip)_textBox.ToolTip).IsOpen = false;
         }
       }
      }
    
    
    Could it be that I have a bug in my .Net 4?


    Regards Uwe
    Wednesday, January 26, 2011 4:53 PM
  • I don't think you have a bug in your .NET.  The tooltip just isn't meant to be used the way you are using it.  You may eventually get it close, but I still think an adorner is a better solution.  Good luck.
    • Marked as answer by UwePfalz Friday, January 28, 2011 5:35 PM
    Wednesday, January 26, 2011 9:14 PM
  • Hi Brian,

    with help from you and Masuadur I could luckily implement the programmatically opening ToolTip with automatic closing after a "Showtime". These are the basics of the solution (C#):

    1. I create a "Stopped" DispatcherTimer with an interval calculated from "ShowDuration" on the Control that needs it and store the Timer in the Controls Tag property.
    2. The DispatcherTimer is wrapped in a class that adds a property to store a reference to the Control in the timer so that I can find the ToolTip in the Tick-Event
    3. When requested the ToolTip is opened by IsOpen property and the Timer is started
    4. When the Timer fires "Tick" the ToolTip is closed and the timer is stopped.

    This works flawlessly w/o any interference to the other functions of the ToolTip. I did in depth testing and it works great. No undocumented or MS internal interfaces are used. It can be used with XAML defined or programmatically attached ToolTips. I have not tested it yet for ToolTips generated from a string.

    I also tried your proposal to use Adorners for a while. When I analysed the Adorner layer with Visual Tree Viewer I discovered that a ToolTip seem to used similar visual handling. So I stopped that approach because the standard ToolTip functionality is better integrated in the solution described above.

    Thank you again for your help.

    If somebody is interested in the code, please let me know. I'll then post it here.


    Regards Uwe
    • Marked as answer by UwePfalz Friday, January 28, 2011 5:36 PM
    Friday, January 28, 2011 5:35 PM