c# uwp tooltip placement 属性 不更新
c# uwp tooltip placement property not updating
在 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 仅在第一次显示工具提示时触发,并且它总是 returns TooltipPlacement 的顶部,无论工具提示显示在控件下方还是上方。
我需要在显示工具提示时触发 CalculateArrowVisibility,并且我需要 TooltipPlacement 属性 来显示工具提示是处于控制之下还是之上。
有人对此有想法吗?
事实是您不能使用 ToolTipService
附加属性(例如 <Button ToolTipService.Placement="Bottom" ToolTipService.ToolTip="!!!" />
)来定义工具提示及其位置。这样 Placement
就不会在实际的 ToolTip
控件本身上设置,这就是为什么它总是 return Top
.
为了让 ToolTip
将其 Placement
值传递给您的自定义依赖项 属性,您必须像下面这样附加它 -
<Button>
<ToolTipService.ToolTip>
<ToolTip Placement="Bottom" Content="Hahaha..." />
</ToolTipService.ToolTip>
</Button>
更新
事实证明,即使应用程序 Window 将工具提示推到其父级上方或下方,其 Placement
值从未改变,改变的是其水平和垂直偏移。
因此,在您的情况下,如果我们能够计算出它的确切垂直偏移量,我们就能够确定工具提示是在(其父级)上方还是下方。
假设我们有 ToolTip
Style,我们可以创建类型 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}}">
因为Grid
的TemplatedParent
是ToolTip
,我们可以用RelativeSource
绑定到link上的ToolTip
带有我们附加的 属性 的屏幕,如上所示。
现在,我们有了对实际 ToolTip
的引用,让我们找出它的偏移量。经过一些挖掘,我发现 ToolTip
的偏移量总是 0
,它们没有用;然而,其父级的偏移量 - 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" />
希望对您有所帮助!
在 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 仅在第一次显示工具提示时触发,并且它总是 returns TooltipPlacement 的顶部,无论工具提示显示在控件下方还是上方。
我需要在显示工具提示时触发 CalculateArrowVisibility,并且我需要 TooltipPlacement 属性 来显示工具提示是处于控制之下还是之上。
有人对此有想法吗?
事实是您不能使用 ToolTipService
附加属性(例如 <Button ToolTipService.Placement="Bottom" ToolTipService.ToolTip="!!!" />
)来定义工具提示及其位置。这样 Placement
就不会在实际的 ToolTip
控件本身上设置,这就是为什么它总是 return Top
.
为了让 ToolTip
将其 Placement
值传递给您的自定义依赖项 属性,您必须像下面这样附加它 -
<Button>
<ToolTipService.ToolTip>
<ToolTip Placement="Bottom" Content="Hahaha..." />
</ToolTipService.ToolTip>
</Button>
更新
事实证明,即使应用程序 Window 将工具提示推到其父级上方或下方,其 Placement
值从未改变,改变的是其水平和垂直偏移。
因此,在您的情况下,如果我们能够计算出它的确切垂直偏移量,我们就能够确定工具提示是在(其父级)上方还是下方。
假设我们有 ToolTip
Style,我们可以创建类型 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}}">
因为Grid
的TemplatedParent
是ToolTip
,我们可以用RelativeSource
绑定到link上的ToolTip
带有我们附加的 属性 的屏幕,如上所示。
现在,我们有了对实际 ToolTip
的引用,让我们找出它的偏移量。经过一些挖掘,我发现 ToolTip
的偏移量总是 0
,它们没有用;然而,其父级的偏移量 - 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" />
希望对您有所帮助!