WPF Popups and ToolTip Behavior – Solution

January 18, 2009

tags: ,
6 comments

Update 26/09/2011 – There’s an updated version available in the archive ‘Zuker.WpfSamples.zip‘ with minor bug fixes.

Finally, the last post of the series ๐Ÿ™‚

Initial posts

WPF Popups and ToolTip behavior – A Journey

WPF Popups and ToolTip Behavior โ€“ Implementation

Attached is my final solution with a working example.

Usage

<Control>
    <controls:RichToolTip.PopupContent>
        <RichToolTip>
            <TextBlock Text=”This will be displayed in the popup” />
        </RichToolTip>
    </controls:RichToolTip.PopupContent>
</Control>

Dependency Properties: (Popup Placement Related)

  1. Placement
  2. PlacementTarget
  3. PlacementRectangle
  4. HorizontalOffset
  5. VerticalOffset

Properties

  1. EnableAnimation โ€“ Applies cool opening effect. (defaults to true)
  2. RelatedObject โ€“ the object the popup content was assigned to. Handy in some cases. (Check the example project)

Commands

  1. CloseCommand โ€“ Closes the opened tooltip. (You can place buttons in the RichToolTip content / contenttemplate which will invoke it in order to close it)

Attached Properties:

  1. PopupContent โ€“ The main entry point for using the RichToolTip (See usage section). you can provide any object which will be made the the tooltip content. (For being able to set placement or other properties you should insert the RichToolTip itself โ€“ see attached code)
  2. HideOnClick โ€“ A helper property for allowing a button which triggers some command to close the opened tooltip as well. I needed it โ€“ seemed useful ๐Ÿ™‚

Known Issues

  1. The popup hides itself when repositioning is needed (window is moved, resize, etc..). This is the common popup behavior (Tooltip and ContextMenu themselves) so I consider this as an overall logical behavior.
  2. In XBAP mode –
    1. Transparency is set through a hack and is only supported in Full Trust mode.
    2. Moving the mouse real slowly towards the popup will cause it to hide (If it bothers you, you could modify the code and use a timer)
    3. Hovering the mouse over the associated element shows the RichToolTip even though the browser window isnโ€™t the active window.

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

6 comments

  1. JustinOctober 15, 2009 ื‘ 11:28

    Thanks for posting this – it was just what I was looking for! Good work.

    Reply
  2. JimMay 19, 2010 ื‘ 20:11

    I am attempting to attach your control to a control in a code. I cannot get anything to fire, but works fine in XAML.

    FrameworkElementFactory popup = new FrameworkElementFactory(typeof(CustomToolTip));
    FrameworkElementFactory popupContent = new FrameworkElementFactory(typeof(CustomToolTip));
    popupContent.SetValue(CustomToolTip.ContentTemplateProperty, ApplicationData.Instance.ToolTipOrder);
    Binding placementBinding = new Binding
    {
    Path = new PropertyPath(“RelatedObject”),
    RelativeSource = new RelativeSource(RelativeSourceMode.Self)
    };
    popupContent.SetBinding(CustomToolTip.PlacementTargetProperty, placementBinding);
    popupContent.SetValue(CustomToolTip.PlacementProperty, PlacementMode.Bottom);
    popupContent.SetValue(CustomToolTip.HorizontalOffsetProperty, 0d);
    popupContent.SetValue(CustomToolTip.VerticalOffsetProperty, 0d);
    Binding tooltipBinding = new Binding
    {
    Source = ApplicationData.Instance,
    Path = new PropertyPath(“DisplayOptions.ShowOrderToolTip”)
    };
    popupContent.SetValue(CustomToolTip.IsEnabledProperty, tooltipBinding);
    popup.SetValue(CustomToolTip.PopupContentProperty, popupContent);
    gridOrder.AppendChild(popup);

    Any help would be create!

    Reply
  3. Amir ZukerMay 20, 2010 ื‘ 11:34

    Hi Jim,

    In addition to trying to do that in code, I see that you use the FrameworkElementFactory, so I guess your goal is to create a template of that in code. (Otherwise, you don’t really need the factory)

    Well, it seems that WPF lacks this ability using the FrameworkElementFactory. The problem is that the attached property PopupContentProperty can’t be set to an actual instance of RichTooltip – not supported by WPF. If you try to set it to another FrameworkElementFactory, you just see the factory class name in the popup, as follows:
    FrameworkElementFactory rectFactory = new FrameworkElementFactory(typeof(Rectangle));
    rectFactory.SetValue(Rectangle.HeightProperty, 130D);
    rectFactory.SetValue(Rectangle.WidthProperty, 130D);
    rectFactory.SetValue(Rectangle.FillProperty, new SolidColorBrush(Colors.Red));

    FrameworkElementFactory popupFactory = new FrameworkElementFactory(typeof(RichToolTip));
    popupFactory.SetValue(RichToolTip.ContentProperty, “This works! You can place in the content anything you like, UI Elements as well!”);

    rectFactory.SetValue(RichToolTip.PopupContentProperty, popupFactory);

    So this is no good.

    What can you do about it?
    1) You can try to change the design so you wouldn’t have to work with FrameworkElementFactory.
    2) If you must use FrameworkElementFactory, you should consider adding another attached property to the RichToolTip, one of type such as DataTemplate and use that one.
    This should work since DataTemplate is allowed in the FrameworkElementFactory, note you would need to load the DataTemplate’s content (LoadContent method) in the RichToolTip and make it its content for it to work of course.

    Hope that helps,

    Amir Zuker

    Reply
  4. DudiNovember 14, 2011 ื‘ 0:02

    Hi AMir,
    thanks for your post.

    What shell i do if i need to define DataTemplate to some class so RichTooltip will display information from that class?
    How do i set the DataContext?

    Reply
  5. Amir ZukerNovember 15, 2011 ื‘ 9:18

    Hi Dudi,

    If I understand correctly, you’re using a DataTempalte to display content inside the RichTooltip, and you need to bind it to data that is part of the DataContext of the element you set the RichToolTip for.

    If that is the case, you can use the RichToolTip property called ‘RelatedObject’.
    This property holds the object that the RichToolTip was set for. For bindings in the data template, you could use FindAncestor method to find the RichToolTip and use the path of ‘RelatedObject.DataContext.WhatEverYouNeed’.
    Another option would be to set the container’s DataContext to the RelatedObject.DataContext as above, and then use direct simple bindings below.

    I hope that helps,
    Amir Zuker

    Reply
  6. RajeshMay 13, 2013 ื‘ 12:51

    How can I make tooltip visible programatically instead of it being shown when mouse is hovered. In my scenario tooltip should be visible based on some data value and not when user hovers mouse.

    Reply