在后面的代码中获取ToolTip的PlacementTarget

时间:2017-02-06 19:39:21

标签: c# xaml uwp tooltip

作为this MSDN page suggests,您应该能够使用数据绑定在工具提示上设置展示位置定位。

在我的UWP应用程序中,我有以下XAML和代码:

<Button x:Name="MyButton">
    <ToolTipService.ToolTip>
        <ToolTip PlacementTarget="{Binding ElementName=MyButton}"
                 Loaded="FunkyMethod">
            <Border Width="150"
                    Height="50"
                    CornerRadius="10"
                    Background="DeepSkyBlue">
                <TextBlock Text="This is a tooltip"
                           HorizontalAlignment="Center"
                           VerticalAlignment="Center"
                           Foreground="White"/>
            </Border>
        </ToolTip>
    </ToolTipService.ToolTip>

    <Button.Content>Button with ToolTip</Button.Content>
</Button>
private void FunkyMethod(object sender, RoutedEventArgs e)
{
    var tooltip = sender as ToolTip;
    var button = tooltip?.PlacementTarget as Button; // always returns NULL for the placement target

    if (tooltip != null && button != null)
    {
        // do something funcky here.
    }
}

但是放置目标永远不会被设置,我总是得到NULL。有谁知道为什么?

对于上下文,我试图编写代码来计算将工具提示放在其父级右侧并垂直居中所需的水平/垂直偏移量。像这样:

enter image description here

但我无法找到实现这一目标的方法(Placement = Right或Top不起作用)。所以我要做的是在运行时代码中执行它,a)设置Placement = Mouse,b)通过PlacementTarget找出父控件,c)找出相对于父控件的鼠标位置,d )计算水平/垂直偏移并为工具提示设置它

2 个答案:

答案 0 :(得分:2)

尝试将传统绑定更改为PlacementTarget="{x:Bind MyButton}"。请注意,默认ModeOneTime,但我认为您的情况可以。

答案 1 :(得分:0)

所以我仍然没有收到微软的回复。正如贾斯汀XL所指出的那样:在某些情况下,Bind会干净利落地工作。但我能够找到适合我的方案的解决方法。以下是片段:

<Style x:Key="ToolTipStyle1"
        TargetType="ToolTip">
    <Setter Property="Placement"
            Value="Mouse" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ToolTip">
                <Grid x:Name="LayoutRoot"
                      MaxWidth="300"
                      MinHeight="36"
                      MaxHeight="300">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>

                    <Polygon Fill="#FF1589EE"
                             Width="10"
                             Height="12"
                             VerticalAlignment="Center"
                             Points="0,6 10,0 10,12" />

                    <Border Grid.Column="1"
                            Background="#FF1589EE">
                        <TextBlock Margin="20,5,5,5"
                                   HorizontalAlignment="Left"
                                   VerticalAlignment="Center"
                                   Foreground="White"
                                   FontSize="16"
                                   TextWrapping="Wrap"
                                   TextTrimming="CharacterEllipsis"
                                   Text="{TemplateBinding Content}" />
                    </Border>

                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="OpenStates">
                            <VisualState x:Name="Closed">
                                <Storyboard>
                                    <FadeOutThemeAnimation TargetName="LayoutRoot" />
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Opened">
                                <Storyboard>
                                    <FadeInThemeAnimation TargetName="LayoutRoot" />
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                </Grid>

            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Button Width="150"
        Height="100"
        PointerMoved="MyButton_OnPointerMoved"
        PointerExited="MyButton_OnPointerExited"
        Content="Parent Control">
    <ToolTipService.ToolTip>
        <ToolTip Loaded="MyToolTip_OnLoaded"
                    Style="{StaticResource ToolTipStyle1}"
                    Content="This is a tooltip" />
    </ToolTipService.ToolTip>
</Button>
public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
    }

    private PointerPoint _devicePointer;
    private FrameworkElement _elementContainingDevicePointer;
    private void MyButton_OnPointerMoved(object sender, PointerRoutedEventArgs e)
    {
        _elementContainingDevicePointer = sender as FrameworkElement;
        _devicePointer = e.GetCurrentPoint(_elementContainingDevicePointer);
    }

    private void MyButton_OnPointerExited(object sender, PointerRoutedEventArgs e)
    {
        _devicePointer = null;
        _elementContainingDevicePointer = null;
    }

    private void MyToolTip_OnLoaded(object sender, RoutedEventArgs e)
    {
        var tooltip = sender as ToolTip;

        if (_devicePointer != null && _elementContainingDevicePointer != null && tooltip != null)
        {
            var x = _elementContainingDevicePointer.ActualWidth - Math.Max(0, _devicePointer.Position.X);
            var y = _elementContainingDevicePointer.ActualHeight / 2 - Math.Max(0, _devicePointer.Position.Y) - tooltip.ActualHeight / 2;

            tooltip.HorizontalOffset = x + 5;
            tooltip.VerticalOffset = y - 10;
        }
    }
}