Windows 7 standard WPF style
The standard WPF tooltip is positioned with a mouse pointer that looks, in my opinion, perfect.
The image below shows your problem.
If you really want to do what you ask, it is possible: you need a code for the style to calculate the horizontal setting, put it in ToolTip.Tag and attach the border of the pointed part to the calculated setting:
ToolTip Revised Style -
<Style TargetType="{x:Type ToolTip}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ToolTip}"> <Grid x:Name="Grid"> <Grid.RowDefinitions> <RowDefinition Height="20" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Rectangle Fill="#fff" Stroke="#FF000000" RadiusX="4" RadiusY="4" Grid.Row="1" /> <Path Fill="#fff" Stretch="Fill" Stroke="#FF000000" HorizontalAlignment="Left" Margin="{TemplateBinding Tag}" Width="20" Grid.Row="0" Data="M 0,21 L 10,0 20,21" /> <ContentPresenter Margin="8" Grid.Row="1" /> </Grid> </ControlTemplate> </Setter.Value> </Setter> <Setter Property="Placement" Value="Bottom" /> <EventSetter Event="Opened" Handler="ToolTipOpenedHandler" /> </Style>
Code for
private void ToolTipOpenedHandler(object sender, RoutedEventArgs e) { ToolTip toolTip = (ToolTip) sender; UIElement target = toolTip.PlacementTarget; Point adjust = target.TranslatePoint(new Point(8, 0), toolTip); toolTip.Tag = new Thickness(adjust.X, 0, 0, -1.5); }
This answers your question as asked,
but not enough if the tooltip is near the bottom of the screen:
To fix this, you can change the code to find that the tooltip is above the target and set the Position to Top tooltip, and the Trigger style of the property is a tooltip with a narrow part under the rectangle -
Complete XAML (includes wide, narrow, and multi-line prompts)
<Window x:Class="WpfToolTip.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="250" Width="250"> <Window.Resources> <Style TargetType="{x:Type ToolTip}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ToolTip}"> <Grid x:Name="Grid"> <Grid.RowDefinitions> <RowDefinition Height="20" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Rectangle MinWidth="40" Fill="#fff" Stroke="#FF000000" RadiusX="4" RadiusY="4" Grid.Row="1" /> <Path Fill="#fff" Stretch="Fill" Stroke="#FF000000" HorizontalAlignment="Left" Margin="{TemplateBinding Tag}" Width="20" Grid.Row="0" Data="M 0,21 L 10,0 20,21" /> <ContentPresenter Margin="8" Grid.Row="1" /> </Grid> </ControlTemplate> </Setter.Value> </Setter> <Setter Property="Placement" Value="Bottom" /> <EventSetter Event="Opened" Handler="ToolTipOpenedHandler" /> <Style.Triggers> <Trigger Property="Placement" Value="Top"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ToolTip}"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="20" /> </Grid.RowDefinitions> <Rectangle MinWidth="40" Fill="#fff" Stroke="#FF000000" RadiusX="4" RadiusY="4" Grid.Row="0" /> <Path Fill="#fff" Stretch="None" Stroke="#FF000000" HorizontalAlignment="Left" Width="20" Grid.Row="1" Data="M 0,0 L 10,20 20,0" Margin="{TemplateBinding Tag}" /> <ContentPresenter Margin="8" Grid.Row="0" /> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Trigger> </Style.Triggers> </Style> </Window.Resources> <Grid> <TextBlock VerticalAlignment="Top" HorizontalAlignment="Left" Background="Aqua" ToolTipService.ToolTip="ToolTip for TopLeft - MMMMMMMMMWWWWWWWWWW">TopLeft</TextBlock> <TextBlock VerticalAlignment="Top" HorizontalAlignment="Right" Background="Aqua" ToolTipService.ToolTip="ToolTip for TopRight - MMMMMMMMMWWWWWWWWWW">TopRight</TextBlock> <TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Background="Aqua" ToolTipService.ToolTip="i">CenterLeft</TextBlock> <TextBlock VerticalAlignment="Center" HorizontalAlignment="Right" Background="Aqua" ToolTipService.ToolTip="i">CenterRight</TextBlock> <TextBlock VerticalAlignment="Bottom" HorizontalAlignment="Left" Background="Aqua" Text="BottomLeft"> <TextBlock.ToolTip> <TextBlock>Multi-line ToolTip for Bottomleft - MMMMMMMMMWWWWWWWWWW<LineBreak/>x<LineBreak/>y<LineBreak/>z</TextBlock> </TextBlock.ToolTip> </TextBlock> <TextBlock VerticalAlignment="Bottom" HorizontalAlignment="Right" Background="Aqua" ToolTipService.ToolTip="ToolTip for BottomRight - MMMMMMMMMWWWWWWWWWW">BottomRight</TextBlock> </Grid> </Window>
Code for
private void ToolTipOpenedHandler(object sender, RoutedEventArgs e) { ToolTip toolTip = (ToolTip)sender; UIElement target = toolTip.PlacementTarget; Point adjust = target.TranslatePoint(new Point(8, 0), toolTip); if (adjust.Y > 0) { toolTip.Placement = PlacementMode.Top; } toolTip.Tag = new Thickness(adjust.X, -1.5, 0, -1.5); }
Final result
The pointed part is now adjusted horizontally when the tooltip is to the right of the screen, and vertically when the tooltip is at the bottom of the screen.