Reputation: 779
I want that when hovering over an app element, the tooltips are not displayed in a popup, but displayed in the app's TextBlock. My knowledge allowed me to achieve it this way. First, I make the resource hint invisible:
<Style x:Key="{x:Type ToolTip}" TargetType="ToolTip">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="HasDropShadow" Value="True" />
</Style>
Next, I write the hint text and events in each element where I want a hint:
WPF:
<Button Content="Button"
ToolTip="Tooltip text 1"
ToolTipOpening="ToolTip"
ToolTipClosing="ToolTip" />
<CheckBox Content="CheckBox"
ToolTip="Tooltip text 2"
ToolTipOpening="ToolTip"
ToolTipClosing="ToolTip" />
(Similarly, other items)
C#:
public void ToolTip(object s, ToolTipEventArgs e)
{
TextBlock.Text =
e.RoutedEvent == ToolTipService.ToolTipOpeningEvent
? (s as FrameworkElement).ToolTip : string.Empty;
}
It works. But is it possible not to indicate events in the element (ToolTipOpening="ToolTip"
and ToolTipClosing="ToolTip"
), but to achieve the desired effect by simply specifying a hint in the element (ToolTip="Tooltip text"
)? Thank you.
Upvotes: 0
Views: 1228
Reputation: 22008
You don't need to use ToolTip
, rather make own reusable attached behavior to mimic tooltip behavior:
public class Behaviors
{
public static TextBlock TextBlock { get; set; }
public static string GetMyToolTip(DependencyObject obj) => (string)obj.GetValue(MyToolTipProperty);
public static void SetMyToolTip(DependencyObject obj, string value) => obj.SetValue(MyToolTipProperty, value);
public static readonly DependencyProperty MyToolTipProperty =
DependencyProperty.RegisterAttached("MyToolTip", typeof(string), typeof(Behaviors), new FrameworkPropertyMetadata(null, (d, e) =>
{
var element = d as UIElement;
element.MouseEnter += (s, a) => TextBlock.Text = e.NewValue.ToString();
element.MouseLeave += (s, a) => TextBlock.Text = null;
}));
}
Then you can simply use it in xaml
<StackPanel>
<TextBlock x:Name="textBlock" />
<Button Content="1" local:Behaviors.MyToolTip="Button 1" />
<Button Content="2" local:Behaviors.MyToolTip="Button 2" />
</StackPanel>
I am not sure how to pass tooltip into TextBox
nice. For the moment you have to set static Behaviors.TextBlock
property to that TextBlock
explicitly:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Behaviors.TextBlock = textBlock;
}
}
Was thinking about MVVM approach where DataContext
has to implement interface or maybe using another attached property to propagating instance set on window all the way down, perhaps someone else can improve the idea.
Upvotes: 2