I have developed a WPF sample project.
Here is the main Window's XAML markup :
<Window x:Class="ToolTipSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
WindowState="Maximized">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Button Click="OnButtonClick">Show ToolTip</Button>
<StatusBar Grid.Row="2">
<StatusBarItem>
<TextBlock Text="TextBlock With ToolTip">
<TextBlock.ToolTip>
<ToolTip x:Name="m_toolTip">
ToolTip
</ToolTip>
</TextBlock.ToolTip>
</TextBlock>
</StatusBarItem>
</StatusBar>
</Grid>
</Window>
Here is the main Window's code-behind without the using statements :
namespace ToolTipSample
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void OnButtonClick(object p_sender, RoutedEventArgs p_args)
{
m_toolTip.IsOpen = true;
}
}
}
I want to programmatically show the ToolTip when the Button is clicked.
I want the ToolTip to be shown above its TextBlock parent.
The ToolTip is automatically shown when the mouse cursor is over the TextBlock and during a constant amount of time C approximatively equal to 5 seconds.
I want the ToolTip to be shown during C when the Button is clicked.
My goals are not achieved in the current project.
The ToolTip is shown when the Button is clicked :
But :
What do I have to do to achieve my goals ?
Any help will be greatly appreciated.
You have a number of problems. The first and simplest to fix is that you are only opening and not closing the ToolTip
. You said I want the ToolTip to be shown during the same amount of time when the Button is clicked, and this is easily implemented handling the PreviewMouseDown
and PreviewMouseUp
events:
private void Button_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
m_toolTip.PlacementTarget = PlacementTarget;
m_toolTip.IsOpen = true;
}
private void Button_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
m_toolTip.IsOpen = false;
}
...
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Button PreviewMouseDown="Button_PreviewMouseDown"
PreviewMouseUp="Button_PreviewMouseUp">Show ToolTip</Button>
<StatusBar Grid.Row="2">
<StatusBarItem>
<TextBlock Name="PlacementTarget" Text="TextBlock With ToolTip">
<TextBlock.ToolTip>
<ToolTip x:Name="m_toolTip" Placement="Top" HorizontalOffset="50"
VerticalOffset="-5">ToolTip</ToolTip>
</TextBlock.ToolTip>
</TextBlock>
</StatusBarItem>
</StatusBar>
</Grid>
Your other problem is slightly more tricky to fix... it seems to me as though there may be some bug involved in the positioning of your ToolTip
. Normally, despite what @icebat said, it is possible to alter the position of a ToolTip
using the ToolTip.Placement
property. This can be set to one of the PlacementMode
Enumerations.
The default value is Mouse
and this is the definition from the linked page on MSDN:
A postion of the Popup control that aligns its upper edge with the lower edge of the bounding box of the mouse and aligns its left edge with the left edge of the bounding box of the mouse. If the lower screen-edge obscures the Popup, it repositions itself to align with the upper edge of the bounding box of the mouse. If the upper screen-edge obscures the Popup, the control repositions itself to align with the upper screen-edge.
This explains why the ToolTip
is displayed far from the TextBlock
placement target... because the Button
and therefore the mouse (when clicking) is far from the TextBlock
. However, by setting the Placement
property to another value should enable a wide range of positions to be achieved. However, setting different values of the Placement
property alone, will just display the ToolTip
in the top left corner of the screen.
To address this situation, you should also set the ToolTip.PlacementTarget
Property, as @icebat correctly noted in the comment, but apparently only from code. Once the PlacementTarget
property has been set, the Placement
property value works as expected. From this linked page:
You can position a ToolTip by setting the PlacementTarget, PlacementRectangle, Placement, HorizontalOffset, and VerticalOffsetProperty properties.
I have achieved my goals.
Sheridan's answer and comments help me.
I have updated my sample project.
The ToolTip is now shown just above the TextBlock when the Button is clicked.
And a Timer's callback method closes the ToolTip after a constant amount of time equal to 2500 ms.
Here is the updated main Window's XAML markup :
<Window x:Class="ToolTipSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
WindowState="Maximized">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Button Click="OnButtonClick">Show ToolTip</Button>
<StatusBar Grid.Row="2">
<StatusBarItem>
<TextBlock Width="900" />
</StatusBarItem>
<StatusBarItem>
<TextBlock x:Name="m_statusMessage" Text="TextBlock With ToolTip" ToolTipService.ShowDuration="30000">
<TextBlock.ToolTip>
<ToolTip x:Name="m_toolTip" Placement="Top">
<TextBlock>
ToolTip ToolTipToolTipToolTipToolTipToo lTipToolTipToolTipT oolTipToolTipT
<LineBreak />
oolTipToolTi pToolTipToo lTipToolTipToolTipToolTipToolTipTo olTipToolTipToolTipTool
<LineBreak />
TipToo lTipToolTipToolTipToo lTipToolTipTo olTipToolTip
</TextBlock>
</ToolTip>
</TextBlock.ToolTip>
</TextBlock>
</StatusBarItem>
</StatusBar>
</Grid>
</Window>
Here is the updated main Window's code-behind without the using statements :
namespace ToolTipSample
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private Timer m_toolTipClosingTimer;
public MainWindow()
{
InitializeComponent();
m_toolTipClosingTimer = new Timer(ToolTipClosingCallBack, null, Timeout.Infinite, Timeout.Infinite);
}
private void OnButtonClick(object p_sender, RoutedEventArgs p_args)
{
m_toolTip.PlacementTarget = m_statusMessage;
m_toolTip.IsOpen = true;
m_toolTipClosingTimer.Change(2500, Timeout.Infinite);
}
private void ToolTipClosingCallBack(object p_useless)
{
Dispatcher.Invoke(() =>
{
m_toolTip.IsOpen = false;
});
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With