Search code examples
wpftouchtooltip

WPF: Tooltip Placement behaves different on touchscreen


I have a ToggleButton with a tooltip:

            <ToggleButton Height="32" Width="32">
                <Image Width="16" Height="16" Source="{someImage} />
                <ToggleButton.ToolTip>
                    <ToolTip Placement="Left" HorizontalOffset="-5">
                        <TextBlock Text="Search"/>
                    </ToolTip>
                </ToggleButton.ToolTip>
            </ToggleButton>

On my PC (regular screens, Windows 8.1) the tooltip is showing to the left of my button, which is correct (see image).

Tooltip on non-touch screen

However, on a pc with a touchscreen, the tooltip is showing to the right (when hovered over with the mouse). Even when the PC has 2 screens, one a touchscreen, the other a regular one, the tooltip is showing to the right on both screens.

Both PC's are running the same OS and .Net version.

When I change the Placement to "Right", the tooltip is showing on the right on a pc without touchscreen and to the left on a pc with a touchscreen.

Why the difference and what can I do so the tooltip is always shown on the left of the button?


Solution

  • Still don't know why it didn't work correctly with the original code, but I found a fix/workaround:

    I've set Placement to Custom, and implemented the ToolTipOpening event handler. There I use the CustomPopupPlacementCallback delegate to set the position of the tooltip manually:

    XAML:

                <ToggleButton Height="32" Width="32" ToolTipOpening="Button_OnToolTipOpening">
                    <Image Width="16" Height="16" Source="{someImage} />
                    <ToggleButton.ToolTip>
                        <ToolTip Placement="Left" HorizontalOffset="-5">
                            <TextBlock Text="Search"/>
                        </ToolTip>
                    </ToggleButton.ToolTip>
                </ToggleButton>
    

    C#:

        private void Button_OnToolTipOpening(object sender, ToolTipEventArgs e)
        {
            var button = sender as ToggleButton;
            if (button == null) return;
            var toolTip = button.ToolTip as ToolTip;
            if (toolTip != null)
            {
                toolTip.PlacementTarget = button;
                toolTip.Placement = PlacementMode.Custom;
                toolTip.CustomPopupPlacementCallback = delegate
                {
                    double offsetY = (button.Height - toolTip.ActualHeight) / 2;
                    double offsetX = -toolTip.ActualWidth - 5;
    
                    return new CustomPopupPlacement[] { new CustomPopupPlacement(new Point(offsetX, offsetY), PopupPrimaryAxis.Horizontal) };
                };
            }
        }