asusralis
Topic Author
Posts: 92
Joined: 30 Jul 2018, 05:03

Problems extending Tooltip.

15 Jul 2020, 09:56

I'm trying to create a Tooltip that follows the mouse cursor, among other things. I have two distinct problems:

1): PlacementTarget kept returning null. I didn't think you had to explicitly set ToolTipService.PlacementTarget, but it seems like you have to? Additionally, once this was set, for some reason PlacementTarget would still be null until I hot reloaded. Once I hot reload, the PlacementTarget would stop being null until I restarted the application! Then I would have to make a minor change and hot reload for it to work again.

2): Once I finally am able to get the PlacementTarget, I can't seem to get the Offsets or a translatetransform to move the tooltip - even when I know MouseMove is being called.

Sorry for the longer code!! Thanks for any help!
    public class SmartToolTip : ToolTip
    {
        private UIElement _targetElement;

        private void PlacementTarget_MouseMove(object sender, MouseEventArgs e)
        {
            if(_targetElement != null)
            {
                var position = e.GetPosition(_targetElement);
                
                // Probably not what I want to set to, but it would still move the offset, right?
                HorizontalOffset = position.X;
                VerticalOffset = position.Y;

                // I tired this too!
                //((UIElement)Template.VisualTree).RenderTransform = new TranslateTransform(position.X, position.Y);
            }
        }

        public SmartToolTip()
        {
            Loaded += (s, e) =>
            {
                Opened += SmartToolTip_Opened;
                ToolTipClosing += SmartToolTip_ToolTipClosing;
            };
        }

        private void SmartToolTip_ToolTipClosing(object sender, ToolTipEventArgs args)
        {
            if (_targetElement != null)
            {
                _targetElement = PlacementTarget;
                _targetElement.MouseMove -= PlacementTarget_MouseMove;
            }
        }

        private void SmartToolTip_Opened(object sender, RoutedEventArgs args)
        {
            if(PlacementTarget != null)
            {
                _targetElement = PlacementTarget;
                _targetElement.MouseMove += PlacementTarget_MouseMove;
            }
        }

        static SmartToolTip()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(SmartToolTip), new FrameworkPropertyMetadata(typeof(SmartToolTip)));
        }
    }
And my style:
        <Setter Property="Placement" Value="Relative" />
        <Setter Property="BorderThickness" Value="10" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:SmartToolTip}">
                    <Border
                        Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                        <StackPanel>
                            <TextBlock Text="{TemplateBinding Header}" />
                            <ContentPresenter />
                        </StackPanel>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>

Tags:
 
User avatar
sfernandez
Site Admin
Posts: 1942
Joined: 22 Dec 2011, 19:20

Re: Problems extending Tooltip.

16 Jul 2020, 13:25

1) PlacementTarget property should be used to explicitly specify which UI element is the target of the ToolTip. It is not intended as an information you can get when tooltip is opened. So if you don't set that property (usually by setting it in ToolTip's target element through attached property ToolTipService.PlacementTarget), you will get a null value. Even after setting the property, its value is coerced so it only returns a valid value when tooltip is visible and connected to the UI tree.

2) Using HorizontalOffset and VerticalOffset to manually move the ToolTip should work, so this is a bug in Noesis. Could you please report it in our bugtracker?
In the meantime you should be able to use a RenderTransform in the ToolTip contents. Please take a look at the following topic for more information: viewtopic.php?f=3&t=1593
 
asusralis
Topic Author
Posts: 92
Joined: 30 Jul 2018, 05:03

Re: Problems extending Tooltip.

19 Jul 2020, 07:32

Isn't this different from WPF? This code works in WPF with a blank project without setting PlacementTarget:
    public class SmartTooltip : ToolTip
    {
        private void UpdatePosition(Point pos)
        {
            HorizontalOffset = pos.X + 0;

            double height = ((FrameworkElement)GetTemplateChild("Root")).ActualHeight;

            VerticalOffset = pos.Y - height;
        }

        protected override void OnOpened(RoutedEventArgs e)
        {
            base.OnOpened(e);

            PlacementTarget.MouseMove += PlacementTarget_MouseMove;

            UpdatePosition(Mouse.GetPosition(PlacementTarget));
        }

        protected override void OnToolTipClosing(ToolTipEventArgs e)
        {
            base.OnToolTipClosing(e);

            PlacementTarget.MouseMove -= PlacementTarget_MouseMove;
        }

        private void PlacementTarget_MouseMove(object sender, MouseEventArgs e)
        {
            var pos = e.GetPosition(PlacementTarget);

            UpdatePosition(pos);
        }

        static SmartTooltip()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(SmartTooltip), new FrameworkPropertyMetadata(typeof(SmartTooltip)));
        }
    }
    <Style TargetType="{x:Type local:SmartTooltip}">
        <Setter Property="Placement" Value="RelativePoint" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:SmartTooltip}">
                    <Border
                        Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        x:Name="Root"
                        BorderThickness="{TemplateBinding BorderThickness}">
                        <StackPanel>
                            <TextBlock Text="{TemplateBinding Header}" />
                            <ContentPresenter />
                        </StackPanel>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
It seems Noesis doesn't have the virtual methods used here, so I had to listen to events in Noesis.
 
asusralis
Topic Author
Posts: 92
Joined: 30 Jul 2018, 05:03

Re: Problems extending Tooltip.

19 Jul 2020, 07:36

Is the root grid in that example directly in the control template? Should I just create a custom control derived from popup instead of tooltip?
 
User avatar
sfernandez
Site Admin
Posts: 1942
Joined: 22 Dec 2011, 19:20

Re: Problems extending Tooltip.

20 Jul 2020, 12:01

Isn't this different from WPF? This code works in WPF with a blank project without setting PlacementTarget
You're right, Noesis deviates from WPF in this, I just verified PlacementTarget its updated with the tool tip owner when it gets opened. We'll fix it for next release.
Is the root grid in that example directly in the control template? Should I just create a custom control derived from popup instead of tooltip?
In your code Root corresponds to the Border defined in the control tempate.

While we fix both issues (PlacementTarget and HorizontalOffset/VerticalOffset), you can create a pseudo ToolTip using a Popup as explained in the topic I mentioned before: viewtopic.php?f=3&t=1593
 
asusralis
Topic Author
Posts: 92
Joined: 30 Jul 2018, 05:03

Re: Problems extending Tooltip.

21 Jul 2020, 11:05

Thanks for the info! I will try it out.

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 1 guest