Overview

The Beep Tooltip System is a layered, singleton-managed framework. The simplified architecture is:

  • ToolTipManager — singleton façade; create, attach, update, and dismiss tooltips with one call.
  • ToolTipConfig / PopoverConfig — immutable (or mutable) configuration objects passed to the manager.
  • ToolTipInstance — the runtime wrapper that owns the CustomToolTip window, show/hide animation, and lifetime.
  • CustomToolTip — the WinForms Form subclass rendered on screen. Delegates all drawing to an IToolTipPainter.
  • IToolTipPainter / ToolTipPainterFactory — strategy pattern; chooses the correct painter per ToolTipLayoutVariant.
  • BeepPopover / BeepPinnedTooltip — persistent non-auto-dismiss windows; extend CustomToolTip.
  • BeepTourManager / BeepTourBuilder — guided-tour engine built on top of the tooltip stack.
  • ToolTipExtensions / ToolTipBuilder — extension methods and fluent builder for attaching tooltips to any Control.
Primary namespace: TheTechIdea.Beep.Winform.Controls.ToolTips
Painters namespace: ...ToolTips.Painters
Helpers namespace: ...ToolTips.Helpers
Entry points: ToolTipManager.Instance · control.SetTooltip() · ToolTipBuilder.Create()

Enumerations

ToolTipType — Semantic type (20 values)

ValueColor ThemeTypical Use
DefaultNeutralGeneral information.
PrimaryBrand primaryPrimary actions, brand-focused information.
SecondaryBrand secondarySupporting / secondary information.
AccentHighlightImportant but non-critical attention.
SuccessGreenConfirmations, completed actions.
WarningOrange / YellowCaution, potential issues.
ErrorRedCritical errors, destructive actions.
InfoBlueTips, documentation links.
HelpContextual help"What is this?" explanations.
ValidationForm feedbackField validation messages.
InteractiveRichTooltips with buttons or links (Popover).
DescriptiveMulti-paragraphLong descriptions, feature explanations.
NotificationAlertReal-time updates anchored to element.
TutorialTour stepOnboarding / guided tours.
ShortcutIDE-styleKeyboard shortcut key-cap badges.
BadgeLabelSupplementary context for badges.
PreviewCard / imageImage/file/link preview (hover card).
ContextMenuMenu itemContext menu item explanations.
StatusHealth indicatorStatus details (online/offline, progress).
HintIntelliSense-styleSuggestions, auto-complete help.
CustomUser-definedFull color override via BackColor/ForeColor/BorderColor.

ToolTipPlacement — 13 positions

ValueDescription
AutoAutomatically picks the best position for available screen space.
Top / TopStart / TopEndAbove target — centred / left-aligned / right-aligned.
Bottom / BottomStart / BottomEndBelow target — centred / left / right.
Left / LeftStart / LeftEndLeft of target — centred / top / bottom.
Right / RightStart / RightEndRight of target — centred / top / bottom.

ToolTipAnimation — 8 values

ValueEffect
NoneInstant show/hide.
FadeOpacity 0→1 (default).
ScaleScale up from center.
SlideSlides in from the placement direction.
BounceEntry bounce effect.
SpringSpring/elastic physics from edge.
ZoomZoom in/out with opacity.
FlipFlip along the axis perpendicular to placement.

ToolTipLayoutVariant — 7 values

ValuePainter UsedDescription
SimpleBeepStyledToolTipPainterSingle-line text, no title (default).
RichBeepStyledToolTipPainterTitle + body text (Material Rich Tooltip).
CardBeepStyledToolTipPainterHeader / body / footer card (DevExpress SuperTip style).
PreviewPreviewToolTipPainterLarge image on top + text below (GitHub hover card).
TourTourToolTipPainterGuided tour step with prev/next navigation.
ShortcutBeepStyledToolTipPainterCompact row with key-cap shortcut badges.
GlassGlassToolTipPainterGlassmorphism / frosted-glass semi-transparent style.

ToolTipTriggerMode

ValueDescription
HoverShow on mouse enter, hide on mouse leave (default).
FocusShow when control receives keyboard focus.
ClickToggle on mouse click.
ManualShow/hide only via programmatic API calls.

EasingFunction

ValueCurve
LinearConstant velocity.
EaseInAccelerates at start.
EaseOutDecelerates at end (default — most natural).
EaseInOutAccelerates then decelerates.
SpringOvershoots and settles.
BounceElastic bounce at end.
BackOutSteps back then forward.

ToolTipArrowStyle

ValueDescription
SharpFlat triangle (Material Design default).
RoundedTriangle with rounded tips (iOS / Figma style).
HiddenNo arrow shown.

ToolTipConfig — Complete Reference

Identity & Content

PropertyTypeDefaultDescription
Keystringauto GUIDUnique identifier; used to update or dismiss a specific tooltip.
Textstring—Primary body text.
Titlestring—Optional header / title row.
Htmlstring—Raw HTML for advanced rendering scenarios.
UseMarkupboolfalseParse lightweight markup in Text: **bold**, *italic*, `code`, [link].
ContentItemsList<ToolTipContentItem>nullOrdered rich content blocks. When set, overrides Text / Title / Html.
Tagobject—Arbitrary user data attached to the config.

Positioning

PropertyTypeDefaultDescription
PositionPoint—Explicit screen position (used when not anchored to a control).
PlacementToolTipPlacementAutoPreferred position relative to the target control.
Offsetint8Pixel gap between the tooltip and its target.
FollowCursorboolfalseTooltip tracks mouse movement while open.

Timing

PropertyTypeDefaultDescription
Durationint (ms)3000Auto-dismiss after this many milliseconds. 0 = indefinite.
ShowDelayint? (ms)500Delay before the tooltip appears after trigger.
HideDelayint? (ms)—Delay before the tooltip disappears after trigger ends.

Appearance — Theme & Style

PropertyTypeDefaultDescription
TypeToolTipTypeDefaultSemantic color theme (Success, Error, Info, Shortcut, etc.).
StyleBeepControlStyleMaterial3Visual design system (Material3, iOS15, Fluent2, …).
LayoutVariantToolTipLayoutVariantSimpleLayout structure: Simple, Rich, Card, Preview, Tour, Shortcut, Glass.
UseBeepThemeColorsbooltrueDerive colors from the active Beep theme instead of tooltip-specific overrides.

Appearance — Colors

PropertyTypeDescription
BackColorColor?Custom background color — overrides theme.
ForeColorColor?Custom text color — overrides theme.
BorderColorColor?Custom border color — overrides theme.

Typography, Layout & Visual Elements

PropertyTypeDefaultDescription
FontFont(theme)Custom font, overrides theme font.
MaxSizeSize?—Maximum size constraint. Tooltip wraps text to fit.
TextHAlignStringAlignmentNearHorizontal body text alignment: Near (left), Center, Far (right).
TextVAlignStringAlignmentNearVertical body text alignment.
ShowArrowbooltrueRender the directional arrow pointing to the target.
ArrowStyleToolTipArrowStyleSharpArrow caret style: Sharp, Rounded, Hidden.
ArrowSizeint8Base pixel size of the arrow. DPI-scaled at paint time.
ArrowOffsetint0Offset of arrow tip from tooltip edge center. Positive = toward End.
ShowShadowbooltrueRender drop shadow.
ClosableboolfalseShow an × close button in the tooltip.

Icons & Images

PropertyTypeDefaultDescription
IconImage—Icon image object.
IconPathstring—Path to icon file (SVG/PNG).
ImagePathstring—Path to main image (displayed in body).
MaxImageSizeSize24×24Maximum icon/image display size.
ApplyThemeOnImagebooltrueColorize SVG images using active theme colors.

Animation

PropertyTypeDefaultDescription
AnimationToolTipAnimationFadeShow/hide animation type.
AnimationDurationint (ms)200Duration of the animation.
AnimationEasingEasingFunctionEaseOutEasing curve applied to all animations.

Trigger & Interaction

PropertyTypeDefaultDescription
TriggerModeToolTipTriggerModeHoverWhat user action shows the tooltip: Hover, Focus, Click, Manual.
PersistOnHoverbooltrueStay open while the mouse is over the tooltip itself (WCAG 1.4.13).
KeyboardTriggerablebooltrueAlso show when the target receives keyboard focus.
PinnableboolfalseShow a pin icon; user can click to keep tooltip on screen.
IsPinnedboolfalseCurrent pin state (managed by ToolTipManager).

Preview Layout

PropertyTypeDefaultDescription
PreviewImagePathstring—Path to image shown at top of Preview-variant tooltip.
PreviewImageSizeSize280×160Size of the preview image area.
PreviewSubtitlestring—Sub-title shown beneath the preview image.
PreviewFooterTextstring—Footer text at the bottom of the preview area.
LoadPreviewAsyncFunc<Task<Image>>nullAsync delegate for lazy-loading the preview image; shows skeleton until ready.

Shortcut Badges

PropertyTypeDescription
ShortcutsList<ShortcutKeyItem>Keyboard shortcuts rendered as key-cap badges in the tooltip footer.
// ShortcutKeyItem
new ShortcutKeyItem { Modifiers = Keys.Control, Key = Keys.S },
new ShortcutKeyItem { Modifiers = Keys.Control | Keys.Shift, Key = Keys.P, DisplayText = "Cmd Palette" }

Step / Tour Layout

PropertyTypeDefaultDescription
CurrentStepint1Current step number shown in step indicator.
TotalStepsint1Total number of tour steps.
StepTitlestring—Step-specific title.
ShowNavigationButtonsbooltrueShow Previous / Next buttons.

Accessibility

PropertyTypeDefaultDescription
MinContrastRatiodouble4.5Minimum WCAG contrast ratio enforced between ForeColor and BackColor (WCAG AA = 4.5).

Lifecycle Callbacks

PropertySignatureDescription
OnShowAction<string>Called when the tooltip becomes visible. Argument is the Key.
OnCloseAction<string>Called when the tooltip is dismissed. Argument is the Key.

ToolTipManager (Singleton Entry Point)

Access via ToolTipManager.Instance. Thread-safe via ConcurrentDictionary; auto-cleanup timer runs every 5 s.

Global Default Properties

PropertyTypeDefaultDescription
DefaultTypeToolTipTypeDefaultFallback type for new tooltips.
DefaultStyleBeepControlStyleMaterial3Fallback visual style.
DefaultShowDelayint (ms)500Default show delay.
DefaultHideDelayint (ms)3000Default auto-dismiss duration.
DefaultFadeInDurationint (ms)150Default fade-in time.
DefaultFadeOutDurationint (ms)100Default fade-out time.
DefaultPlacementToolTipPlacementAutoDefault placement when not specified in config.
EnableAnimationsbooltrueGlobal animation toggle. Set false to disable all transitions.
EnableAccessibilitybooltrueSet AccessibleDescription / AccessibleName on wired controls.

Show Methods

MethodReturnsDescription
ShowTooltipAsync(config)Task<string>Show a fully configured tooltip. Returns the Key.
ShowTooltipAsync(text, location, duration)Task<string>Quick text tooltip at a screen point.
ShowTooltipAsync(title, text, location, type?)Task<string>Titled tooltip at a screen point.

Hide & Update Methods

MethodDescription
HideTooltipAsync(key)Hide and dispose a specific tooltip by its key.
HideAllTooltipsAsync()Hide all active tooltips simultaneously.
UpdateTooltip(key, newText, newTitle)Update content of a running tooltip without re-creating it.
UpdateTooltipPosition(key, newPosition)Move a running tooltip (follow-cursor scenarios).

Control Attachment

MethodDescription
SetTooltip(control, text, config?)Attach a hover tooltip to a control. Wires MouseEnter/Leave automatically.
SetTooltip(control, title, text, type, style)Attach a titled/typed tooltip to a control.
RemoveTooltip(control)Detach the tooltip from a control and unregister event handlers.

Query Methods

MemberDescription
IsTooltipActive(key)True if a tooltip with the given key is currently shown.
GetActiveTooltipKeys()Enumerate keys of all visible tooltips.
ActiveTooltipCountCount of currently active tooltips.

Extension Methods & Fluent Builder

ToolTipExtensions (Control extension methods)

MethodDescription
control.SetTooltip(text)Attach a simple hover tooltip.
control.SetRichTooltip(text, title?, type)Attach a titled tooltip with a ToolTipType.
control.SetTooltip(config)Attach with full ToolTipConfig.
control.RemoveTooltip()Remove the attached tooltip.
await control.ShowNotificationAsync(text, type, duration)Show a transient notification above the control.
await control.ShowSuccessAsync(text, duration)Green success notification.
await control.ShowErrorAsync(text, duration)Red error notification (4 s default).
await control.ShowWarningAsync(text, duration)Orange warning notification.
await control.ShowInfoAsync(text, duration)Blue info notification.

ToolTipBuilder — Fluent API

// Attach to a control
ToolTipBuilder.Create()
    .WithTitle("Save File")
    .WithText("Saves the current document to disk.")
    .WithTheme(ToolTipType.Info)
    .WithPlacement(ToolTipPlacement.Top)
    .WithAnimation(ToolTipAnimation.Slide)
    .WithArrow(true)
    .WithShadow(true)
    .Closable(false)
    .AttachTo(btnSave);

// Show at a point
await ToolTipBuilder.Create()
    .WithText("Processing…")
    .WithTheme(ToolTipType.Notification)
    .WithDuration(2000)
    .ShowAsync(cursorPosition);

All builder methods return this for chaining. Available builder methods:

MethodDescription
WithText(text)Set body text.
WithTitle(title)Set title.
WithTheme(type)Set ToolTipType semantic theme.
WithCustomColors(back, fore, border?)Override colors (sets Type = Custom).
WithPlacement(placement)Set preferred position.
WithAnimation(animation)Set show/hide animation.
WithDuration(ms)Set auto-dismiss duration.
WithDelay(showMs, hideMs?)Set show and hide delays.
WithMaxSize(size)Constrain tooltip dimensions.
WithFont(font)Override font.
WithIcon(image)Set icon image object.
WithIconPath(path)Set icon from file path.
FollowCursor(bool)Enable cursor-tracking.
WithArrow(bool)Show/hide arrow.
WithShadow(bool)Show/hide shadow.
Closable(bool)Show/hide × button.
OnShow(action)Show callback.
OnClose(action)Close callback.
Build()Return the ToolTipConfig.
ShowAsync(point)Build and show at position.
AttachTo(control)Build and attach to control.

BeepPopover — Persistent Popup

A persistent window that stays open until explicitly dismissed. Extends CustomToolTip. Configured via PopoverConfig (extends ToolTipConfig).

PopoverConfig Properties

PropertyTypeDefaultDescription
PrimaryButtonTextstring—Label for primary/confirm button. Omit to hide.
SecondaryButtonTextstring—Label for secondary/cancel button. Omit to hide.
PrimaryButtonTypeToolTipTypePrimaryColor theme of the primary button (e.g. Error for destructive actions).
OnPrimaryClickAction<string>—Fired when primary button clicked. Argument is the Key.
OnSecondaryClickAction<string>—Fired when secondary button clicked or popover cancelled.
DismissOnClickOutsidebooltrueClose when the user clicks outside the popover.
DismissOnEscapebooltrueClose when the user presses Escape.
MaxPopoverWidthint360Maximum width of the popover in pixels.

BeepPopover Public API

MethodDescription
ApplyPopoverConfig(cfg)Apply a PopoverConfig and mount action buttons.
ConfirmAndClose()Invoke OnPrimaryClick callback and close.
DismissAsCancel()Invoke OnSecondaryClick callback and close.
// Confirmation popover
await ToolTipManager.Instance.ShowPopoverAsync(btnDelete, new PopoverConfig
{
    Title               = "Delete item?",
    Text                = "This action cannot be undone.",
    Type                = ToolTipType.Error,
    PrimaryButtonText   = "Delete",
    PrimaryButtonType   = ToolTipType.Error,
    SecondaryButtonText = "Cancel",
    TriggerMode         = ToolTipTriggerMode.Click,
    Placement           = ToolTipPlacement.Top,
    OnPrimaryClick      = key => DeleteItem(),
    OnSecondaryClick    = key => { /* do nothing */ }
});

BeepPinnedTooltip — Draggable Pinned Window

Extends BeepPopover. When pinned, the window stays on screen and can be dragged anywhere. A pin button appears in the top-right corner.

MemberDescription
IsPinnedbool property — get/set pin state. When true, auto-dismiss is disabled.
IsPinnedChangedEvent — fires when pin state toggles.
Pin()Pin the tooltip at its current screen position.
Unpin()Unpin — tooltip will auto-dismiss on next hide trigger.
ApplyPinnedConfig(config, screenLocation)Apply config with pre-set IsPinned and position.
// Enable pinnable tooltip via ToolTipConfig
btnHelp.SetTooltip(new ToolTipConfig
{
    Title     = "Detailed Help",
    Text      = "This panel controls the …",
    Pinnable  = true,
    Closable  = true,
    Duration  = 0,          // no auto-dismiss
    Placement = ToolTipPlacement.Right
});

Guided Tour — BeepTourManager & BeepTourBuilder

A lightweight guided-tour / onboarding engine built on the tooltip stack. All tooltips are ToolTipLayoutVariant.Tour with step indicators and Prev/Next navigation.

BeepTourStep Properties

PropertyTypeDescription
TargetControlControlThe control to highlight and anchor this step's tooltip to.
TitlestringPrimary heading.
BodystringDescriptive text.
ImagePathstringOptional image shown above the text.
PlacementToolTipPlacementWhere to anchor the tooltip relative to TargetControl.
OnEnterActionCalled just before this step is shown (e.g. scroll into view).
OnLeaveActionCalled just after this step is dismissed.

BeepTourManager API

MemberDescription
BeepTourManager.InstanceSingleton instance.
IsRunningTrue while a tour is active.
CurrentStep1-based current step number.
TotalStepsTotal step count.
CreateTour()Return a new BeepTourBuilder bound to this manager.
LoadTour(steps)Load a pre-built step list.
StartAsync() / Start()Begin the tour from step 1.
NextAsync() / Next()Advance to next step; completes tour if on last step.
PreviousAsync() / Previous()Go back to previous step.
Skip()Cancel tour without completing.
TourStartedEvent — fired when tour begins.
StepChangedEventHandler<(int current, int total)> — fired on each step transition.
TourCompletedEvent — fired when all steps completed.
TourSkippedEvent — fired when Skip() called.

BeepTourBuilder Fluent API

MethodDescription
AddStep(control, title, body, placement)Add a basic step.
AddStep(BeepTourStep)Add a fully pre-configured step.
WithCallbacks(onEnter?, onLeave?)Attach lifecycle callbacks to the most recently added step.
WithImage(imagePath)Attach an image to the most recently added step.
Build()Validate, load into BeepTourManager, and return the manager for chaining.
// ── Fluent builder ──────────────────────────────────────────────
BeepTourManager.Instance
    .CreateTour()
    .AddStep(btnNew,     "Create New",  "Click here to create a new record")
    .AddStep(btnSave,    "Save",        "Saves all pending changes")
        .WithCallbacks(onEnter: () => btnSave.Focus())
    .AddStep(tbxSearch,  "Search",      "Type to filter the grid rows")
        .WithImage(@"Assets\tour-search.png")
    .AddStep(btnExport,  "Export",      "Export results to Excel or CSV",
                         ToolTipPlacement.Left)
    .Build()
    .Start();

// ── Events ──────────────────────────────────────────────────────
BeepTourManager.Instance.TourCompleted += (s, e) =>
    Properties.Settings.Default.TourSeen = true;

BeepTourManager.Instance.StepChanged += (s, args) =>
    lblStep.Text = $"Step {args.current} of {args.total}";

Painter Pipeline

All rendering is delegated through IToolTipPainter. ToolTipPainterFactory selects the correct painter based on ToolTipLayoutVariant.

Painter ClassUsed For
BeepStyledToolTipPainterAll standard variants: Simple, Rich, Card, Shortcut, and fallback.
PreviewToolTipPainterToolTipLayoutVariant.Preview — image-header hover card.
TourToolTipPainterToolTipLayoutVariant.Tour — prev/next step navigation UI.
GlassToolTipPainterToolTipLayoutVariant.Glass — glassmorphism frosted style.

IToolTipPainter Interface

public interface IToolTipPainter
{
    void Paint(Graphics g, Rectangle bounds, ToolTipConfig config,
               ToolTipPlacement placement, IBeepTheme theme);
    void PaintBackground(Graphics g, Rectangle bounds, ToolTipConfig config, IBeepTheme theme);
    void PaintBorder    (Graphics g, Rectangle bounds, ToolTipConfig config, IBeepTheme theme);
    void PaintShadow    (Graphics g, Rectangle bounds, ToolTipConfig config);
    void PaintArrow     (Graphics g, Point position, ToolTipPlacement placement,
                         ToolTipConfig config, IBeepTheme theme);
    void PaintContent   (Graphics g, Rectangle bounds, ToolTipConfig config, IBeepTheme theme);
    Size CalculateSize  (Graphics g, ToolTipConfig config);
}

Registering a custom painter

// Implement the interface
public class MyCustomPainter : ToolTipPainterBase
{
    public override void PaintContent(Graphics g, Rectangle bounds,
                                      ToolTipConfig config, IBeepTheme theme)
    {
        // custom rendering
    }
}

// Use it via ToolTipLayoutVariant.Custom requires overriding GetPainter,
// or set directly on the CustomToolTip instance before Show().

Code Examples

Simple tooltip on any control

btnSave.SetTooltip("Save your changes (Ctrl+S)");

Rich titled tooltip

btnSave.SetRichTooltip(
    text:  "Saves all unsaved changes to the current document.",
    title: "Save File",
    type:  ToolTipType.Info
);

Shortcut badge tooltip

btnSave.SetTooltip(new ToolTipConfig
{
    Title         = "Save File",
    Text          = "Save the current document.",
    LayoutVariant = ToolTipLayoutVariant.Shortcut,
    Shortcuts     = new List<ShortcutKeyItem>
    {
        new ShortcutKeyItem { Modifiers = Keys.Control, Key = Keys.S }
    }
});

Preview hover card (lazy image)

thumbnailLabel.SetTooltip(new ToolTipConfig
{
    Title             = "Project Screenshot",
    Text              = "Last modified: today",
    LayoutVariant     = ToolTipLayoutVariant.Preview,
    PreviewSubtitle   = "screenshot.png · 2.4 MB",
    PreviewFooterText = "Click to open",
    LoadPreviewAsync  = async () => await LoadThumbnailAsync(projectId),
    Placement         = ToolTipPlacement.Right
});

Transient notification above a button

// After form validation
await txtEmail.ShowErrorAsync("Please enter a valid email address.");

// After a successful save
await btnSave.ShowSuccessAsync("Saved!", duration: 1500);

Glass-style tooltip

statusIcon.SetTooltip(new ToolTipConfig
{
    Title         = "System Status",
    Text          = "All services running normally.",
    Type          = ToolTipType.Success,
    LayoutVariant = ToolTipLayoutVariant.Glass,
    Animation     = ToolTipAnimation.Zoom,
    Placement     = ToolTipPlacement.BottomStart
});

Programmatic tooltip at cursor

private async void OnGridCellHover(object sender, CellHoverEventArgs e)
{
    var pos = grid.PointToScreen(e.CellBounds.Location);

    _hoverKey = await ToolTipManager.Instance.ShowTooltipAsync(new ToolTipConfig
    {
        Title     = e.ColumnHeader,
        Text      = e.CellValue?.ToString() ?? "(empty)",
        Type      = ToolTipType.Default,
        Duration  = 0,          // keep until cell leave
        Placement = ToolTipPlacement.Top,
        Position  = pos
    });
}

private async void OnGridCellLeave(object sender, EventArgs e)
{
    if (_hoverKey != null)
    {
        await ToolTipManager.Instance.HideTooltipAsync(_hoverKey);
        _hoverKey = null;
    }
}

Follow-cursor tooltip

ToolTipBuilder.Create()
    .WithText("Drag to resize")
    .WithTheme(ToolTipType.Hint)
    .WithAnimation(ToolTipAnimation.Fade)
    .FollowCursor(true)
    .WithArrow(false)
    .AttachTo(resizeHandle);

Best Practices

  • Use extension methods for simple cases. control.SetTooltip("text") is always sufficient for plain hover tooltips — no manual ToolTipManager calls needed.
  • Use ToolTipBuilder for one-off styled tooltips. The fluent API avoids repeatedly constructing ToolTipConfig objects.
  • Use ToolTipType semantically. Choose Error for errors, Warning for cautions — the type drives accessible color selection including WCAG contrast enforcement (MinContrastRatio).
  • Set Duration = 0 for popovers and pinnable tooltips. Never let an interactive or pinned tooltip auto-dismiss.
  • Use PersistOnHover = true (default) for all rich tooltips. This satisfies WCAG 1.4.13 — users must be able to move the mouse over the tooltip.
  • Wire TriggerMode = Click for destructive confirmation popovers. Hover-triggered confirmation dialogs are confusing; click-triggered ones are expected.
  • Prefer LoadPreviewAsync for heavy images in Preview tooltips — the skeleton placeholder displays immediately while the image loads.
  • Call HideAllTooltipsAsync() when opening a modal dialog to prevent orphaned tooltips underneath.
  • Disable animations during tests: ToolTipManager.Instance.EnableAnimations = false;
  • Always set TriggerMode = Manual when managing lifecycle yourself (grid cells, map pins, etc.) so the manager does not interfere with your MouseEnter/Leave logic.
  • Tour: call Properties.Settings.Default.TourSeen after TourCompleted to avoid showing the tour to returning users.