时间:2019-05-17 标签:c#uwptooltipplacementpropertynotupdate

标签 c# uwp tooltip dependency-properties templatebinding

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

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

    <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 正在获取工具提示放置的信息,因此我可以根据工具提示是否处于控制之下或之上来显示它。

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

    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 仅在第一次显示工具提示时才会触发,并且无论工具提示显示在控件下方还是上方,它始终返回 TooltipPlacement 的 Top。

每当显示工具提示时,我需要触发CalculateArrowVisibility,并且我需要 TooltipPlacement 属性来显示工具提示是在控制之下还是之上。

有人对此有想法吗?

最佳答案

事实是您不能使用 ToolTipService附加属性(例如 <Button ToolTipService.Placement="Bottom" ToolTipService.ToolTip="!!!" /> )来定义工具提示及其位置。这样Placement未在实际ToolTip上设置控制本身,这就是为什么它总是返回 Top .

为了拥有ToolTip传下其Placement值到您的自定义依赖属性,您必须像下面一样附加它 -

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

更新

事实证明,即使应用程序窗口将工具提示推到其父窗口上方或下方,其 Placement值永远不会改变,改变的是它的水平和垂直偏移。

因此,在您的情况下,如果我们可以计算出其精确的垂直偏移量,我们就能够确定工具提示是位于其父级之上还是之下。

假设我们有 ToolTip 样式就位,我们可以创建 ToolTip 类型的附加属性并将其附加到 Grid包含 ArrowDown控制。

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

因为 TemplatedParent Grid的是ToolTip ,我们可以使用RelativeSource绑定(bind)以链接 ToolTip在带有我们附加属性的屏幕上,如上所示。

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

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 可以工作。

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

希望这有帮助!

关于时间:2019-05-17 标签:c#uwptooltipplacementpropertynotupdate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44881804/

相关文章:

c# - 如何在紧凑框架(Windows CE)中从链接标签中删除下划线

c# - 通过评论禁用所有 Resharper 警告

C# 套接字 StreamReader.ReadToEnd 永远等待

C# Windows 通用 10 TopMost 窗口

javascript - 相对于响应式页面的 SVG 元素重新定位工具提示

java - 如何在 Java 中制作 Windows 7 工具提示

jQueryUI 工具提示四处跳跃

c# - 查找以大写字母开头的最后一个子字符串

c# - 在 .NET 中加载 ECC 私钥

CSS 与 XAML 测量