c#uwp工具提示放置属性未更新 [英] c# uwp tooltip placement property not updating

查看:93
本文介绍了c#uwp工具提示放置属性未更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C#UWP中,我正在创建自定义工具提示样式。

In C# UWP I am creating custom tooltip style.

我更改了工具提示的默认样式,如下所示。

I have changed the default style of tooltip as below.

    <Style TargetType="ToolTip">
        <Setter Property="Foreground" Value="White" />
        <Setter Property="Background" Value="{ThemeResource SystemControlBackgroundChromeMediumLowBrush}" />
        <Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundChromeHighBrush}" />
        <Setter Property="BorderThickness" Value="{ThemeResource ToolTipBorderThemeThickness}" />
        <Setter Property="FontSize" Value="{ThemeResource ToolTipContentThemeFontSize}" />
        <Setter Property="Padding" Value="40,40,40,35"/>

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ToolTip">

                    <Grid Background="Transparent">

                        <Grid 
                            MinWidth="100"
                            MinHeight="90"
                            Height="{TemplateBinding Height}"
                            Width="{TemplateBinding Width}" 
                            Padding="15" 
                            Background="Transparent">

                         <local:ArrowDown  x:Name="arrowDown" TooltipPlacement="{TemplateBinding Placement}"/>

我的自定义控件ArrowDown正在获取ToolTip位置的信息,因此我可以显示它取决于tooltip是否

And my custom control ArrowDown is getting information of ToolTip placement, so I can show it depends if tooltip is under or above control.

在ArrowDown控件中,我添加了DependencyProperty,如下所示:

In the ArrowDown control I have added a DependencyProperty as below:

    public PlacementMode TooltipPlacement
    {
        get { return (PlacementMode)GetValue(TooltipPlacementProperty); }
        set { SetValue(TooltipPlacementProperty, value); }
    }

    public static readonly DependencyProperty TooltipPlacementProperty =
        DependencyProperty.Register("TooltipPlacement", typeof(PlacementMode), typeof(ArrowDown), new PropertyMetadata(null, TooltipPlacementChangedCallback));

    private static void TooltipPlacementChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var self = (ArrowDown)d;
        self.CalculateArrowVisibility();
    }

    // Method to show or hide arrow
    private void CalculateArrowVisibility()
    {
    }

问题是,仅当第一次显示工具提示时,CalculateArrowVisibility才被触发,并且无论工具提示是否为,它始终返回Top作为TooltipPlacement

And the problem is that the CalculateArrowVisibility is fire only the first time when tooltip is shown, and it always returns Top for TooltipPlacement, no matter if tooltip is shown below or above control.

无论何时显示工具提示,我都需要触发CalculateArrowVisibility,并且我需要TooltipPlacement属性来显示工具提示是处于控制之下还是处于控制之上。

I need CalculateArrowVisibility to be fired whenever the tooltip is shown, and I need TooltipPlacement property to show if tooltip is Under or Above control.

有人对此有想法吗?

推荐答案

事实是,您不能使用附加的 ToolTipService 属性(例如< Button ToolTipService.Placement = Bottom ToolTipService.ToolTip = !!! /> )来定义工具提示及其位置。这样,不会在实际的 ToolTip 控件本身上设置 Placement ,这就是为什么它将始终返回<$ c的原因$ c>顶部。

The fact is that you cannot use the ToolTipService attached properties (e.g. <Button ToolTipService.Placement="Bottom" ToolTipService.ToolTip="!!!" />) to define the tooltip and it placement. This way the Placement is not set on the actual ToolTip control itself, and that's why it will always return Top.

为了使 ToolTip 向下传递 Placement 值到您的自定义依赖项属性中,则必须将其附加为以下内容-

In order to have the ToolTip pass down its Placement value to your custom dependency property, you will have to attach it like the following -

<Button>
    <ToolTipService.ToolTip>
        <ToolTip Placement="Bottom" Content="Hahaha..." />
    </ToolTipService.ToolTip>
</Button>






更新



事实证明,即使应用程序窗口将工具提示推到其父对象的上方或下方,其 Placement 的值也不会改变,但其水平&


Update

Turns out that even though the app Window pushes the tooltip above or below its parent, its Placement value is never changed, what's changed is its horizontal & vertical offsets.

因此,在您的情况下,如果我们可以算出其确切的垂直偏移量,则可以确定工具提示是在上方还是在下方(其父级)。

So, in your case, if we could work out its exact vertical offset, we would be able to determine whether the tooltip is above or below (its parent).

鉴于我们已有 ToolTip Style ,我们可以创建一个类型为 ToolTip 的附加属性,并将其附加到包含 ArrowDown Grid c $ c>控件。

Given we have a ToolTip Style in place, we can create an attached property of type ToolTip and attach it to the Grid that contains the ArrowDown control.

<Grid MinWidth="100"
      MinHeight="90"
      Height="{TemplateBinding Height}"
      Width="{TemplateBinding Width}"
      Padding="15"
      Background="Transparent"
      local:ToolTipHelper.ToolTip="{Binding RelativeSource={RelativeSource TemplatedParent}}">

因为<$ c的 TemplatedParent $ c> Grid 是 ToolTip ,我们可以使用 RelativeSource 绑定来链接工具提示在屏幕上具有我们附加的属性,如上所示。

Because the TemplatedParent of the Grid is the ToolTip, we can use RelativeSource binding to link the ToolTip on the screen with our attached property, as shown above.

现在,我们引用了实际的工具提示,让我们找到它的偏移量。经过一番挖掘,我发现 ToolTip 的偏移量始终为 0 ,它们没有用;但是,其父级的偏移量- Popup 有时会为我提供正确的值,但并非总是如此。这是因为我正在使用 Opened 事件,但尚未填充这些值;一旦将其更改为 SizeChanged ,他们就一直在给我期望值。

Now, we have a reference to the actual ToolTip, let's find its offsets. After some digging, I've found that the offsets of the ToolTip are always 0, they are useless; however, the offsets of its parent - a Popup, sometimes gives me the correct values, but not always. This is because I was using the Opened event where those values weren't yet populated; as soon as I changed it to SizeChanged, they have been giving me the expected values.

public static class ToolTipHelper
{
    public static ToolTip GetToolTip(DependencyObject obj)
    {
        return (ToolTip)obj.GetValue(ToolTipProperty);
    }
    public static void SetToolTip(DependencyObject obj, ToolTip value)
    {
        obj.SetValue(ToolTipProperty, value);
    }
    public static readonly DependencyProperty ToolTipProperty =
        DependencyProperty.RegisterAttached("ToolTip", typeof(ToolTip), typeof(ToolTipHelper), 
        new PropertyMetadata(null, (s, e) =>
        {
            var panel = (Panel)s; // The Grid that contains the ArrowDown control.
            var toolTip = (ToolTip)e.NewValue;

            // We need to monitor SizeChanged instead of Opened 'cause the offsets
            // are yet to be properly set in the latter event.
            toolTip.SizeChanged += (sender, args) =>
            {
                var popup = (Popup)toolTip.Parent; // The Popup that contains the ToolTip.

                // Note we have to use the Popup's offset here as the ToolTip's are always 0.
                var arrowDown = (ArrowDown)panel.FindName("arrowDown");
                arrowDown.TooltipPlacement = popup.VerticalOffset > 0
                    ? PlacementMode.Bottom
                    : PlacementMode.Top;
            };
        }));
}

现在,通过这种方法,您应该可以使用 ToolTipService 的附加属性。因此,以下XAML将起作用。

Now, with this approach, you should be able to use the ToolTipService attached properties too. So the following XAML would work.

<Button ToolTipService.ToolTip="!!!" Content="Hover Me" />

希望这会有所帮助!

这篇关于c#uwp工具提示放置属性未更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆