tags:

views:

210

answers:

2

What is the minimum number of steps required to display a tooltip when the following control gets focus?

<TextBox ToolTip="Hello there!" ... />

I tried the following in GotFocus

    private void ..._GotFocus(object sender, RoutedEventArgs e) {
        var element = (FrameworkElement)sender;
        var tooltip = element.ToolTip;
        if (!(tooltip is ToolTip)) {
            tooltip = new ToolTip { Content = tooltip };
            element.ToolTip = tooltip;
        }

        ((ToolTip)tooltip).IsOpen = true;
    }

However, it seems to ignore the ToolTipService.Placement for this control and SystemParameters.ToolTipPopupAnimationKey set up level higher.

How can I make it work and honor all settings that generally work for tooltips (except the timing, obviously)?

A: 

Don't have a Windows machine to test, but I would have thought:

<TextBox x:Name="textBox">
    <TextBox.ToolTip>
        <ToolTip IsOpen="{Binding IsKeyboardFocusWithin, ElementName=textBox}">
            Whatever
        </ToolTip>
    </TextBox.ToolTip>
</TextBox>

HTH,
Kent

Kent Boogaart
`ToolTipService.IsOpen` unfortunately does not have an available setter (as compared to `ToolTip.IsOpen`).
Andrey Shchekin
Sorry, I shouldn't answer questions when I'm uncertain and can't test :) How about my revision - does that help?
Kent Boogaart
This would work, yes, and this is my current solution, however I really do not want to rewrite the TetBox itself. I want to make it into an attached property which will not require user to write tooltip as `ToolTip`. After all, `ToolTipService` does not.
Andrey Shchekin
I've tried this solution, but I can't seem to Bind to anything outside of the tooltip. Any ideas?
Chris Nicol
A: 

I'd build an IsKeyboardFocused binding in the attached property, like this:

 public class ShowOnFocusTooltip : DependencyObject
 {
   public object GetToolTip(...
   public void SetToolTip(...
   public static readonly DependencyProperty ToolTipProperty = DependencyProperty.RegisterAttached(..., new PropertyMetadata
   {
     PropertyChangedCallback = (obj, e) =>
     {
       ToolTipService.SetToolTip(obj,
         e.NewValue==null ? null :
         BuildToolTip(obj, e.NewValue));
     }
   });

   private object BuildToolTip(DependencyObject control, object content)
   {
     var tooltip = content is ToolTip ? (ToolTip)content : new ToolTip { Content = content };
     tooltip.SetBinding(ToolTip.IsOpenProperty,
       new Binding("IsKeyboardFocusWithin") { Source = control });
     return tooltip;
   }
Ray Burns
That's very similar to my original solution. I haven't tried it yet, but `new Tooltip` seem to imply the same problem: ignored `ToolTipService.Placement` and `SystemParameters.ToolTipPopupAnimationKey`. I can copy the first one, but I really want to just get the ToolTip that service uses, since it will be future-proof in terms of properties and styles.
Andrey Shchekin
The "new Tooltip" code is for convenience when you don't want to set any of those properties. If you do, your XAML can give an explicit ToolTipPlacement etc: `<TextBox><my:ShowOnFocusTooltip.Tooltip><ToolTip Placement="..." ... /></my:ShowOnFocusTooltip.Tooltip></TextBox>`
Ray Burns
The problem is, for the user of the attached property, it is not obvious that `ToolTipService.Placement` does not work anymore and that he should use explicit `ToolTip` with `Placement` instead. Of course, I can throw an exception, but this would violate the rule of least surprise. And the whole question is about preserving original way of configuring tooltips.
Andrey Shchekin