Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
510 views
Welcome To Ask or Share your Answers For Others

1 Answer

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>

demo

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...