查找逻辑或Visual树弹出工具提示
说我有一个工具提示
在XAML像这样指定的样式:
Say I have a ToolTip
with a style specified in XAML like this:
<Button Content="Click me" ToolTip="Likes to be clicked">
<Button.Resources>
<Style TargetType="{x:Type ToolTip}" BasedOn="{StaticResource {x:Type ToolTip}}">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="HasDropShadow" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToolTip}">
<StackPanel Background="Wheat" Height="200" Width="200">
<TextBlock x:Name="TxbTitle" FontSize="24" Text="ToolTip" Background="BurlyWood" />
<ContentPresenter />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Resources>
</Button>
由于我在引用按钮
并且该工具提示
显示时,我怎么能找到工具提示弹出
/ code>(后来找其视觉的孩子,如: TxbTitle
)?
Given I have a reference to the Button
and that the ToolTip
is showing, how can I find the Popup
of the ToolTip
(and later look for its visual children, e.g. TxbTitle
)?
更新
根据 pushpraj的回答我能够得到保持的(全)可视化树,它看起来是这样的:
Based on pushpraj's answer I was able to get a hold on the (full) visual tree, and it looks like this:
System.Windows.Controls.Primitives.PopupRoot
System.Windows.Controls.Decorator
System.Windows.Documents.NonLogicalAdornerDecorator
System.Windows.Controls.ToolTip
System.Windows.Controls.StackPanel
System.Windows.Controls.TextBlock (TxbTitle)
System.Windows.Controls.ContentPresenter
System.Windows.Controls.TextBlock
System.Windows.Documents.AdornerLayer
在这里我可以找到 TxbTitle
的TextBlock 。code>
(逻辑树是这样的:)
System.Windows.Controls.Primitives.Popup
System.Windows.Controls.ToolTip
System.String
pushpraj的回答却是基于我能获得工具提示
实例举行。我已经得到的是按钮
而已,而 Button.ToolTip
属性返回字符串喜欢被点击
,而不是工具提示
实例。
pushpraj's answer is however based on that I can get hold of the ToolTip
instance. What I have got is the Button
only, and Button.ToolTip
property returns the string "Likes to be clicked"
, not the ToolTip
instance.
所以更具体地说,问题是,我可以以某种方式获得的工具提示
的或的的弹出
搁置当我的一切是按钮
So more specifically, the question is, can I get hold of the ToolTip
or the Popup
in some way when all I've got is the Button
.
(疯狂的想法:是有一些方法来枚举所有打开弹出
S')
(Crazy idea: is there some way to enumerate all open Popup
s?)
A 工具提示
是一种弹出
它承载工具提示内容
A ToolTip
is a kind of Popup
which hosts the tooltip content
和因为弹出窗口的在一个单独的窗口中承载所以它有它自己的逻辑和可视树
And since a Popup is hosted in a separate window so it have it's own logical and visual tree
下面您的信息是一个提示
for your information below are the Visual and Logical tree for a tooltip
视觉树
System.Windows.Controls.Primitives.PopupRoot
System.Windows.Controls.Decorator
System.Windows.Documents.NonLogicalAdornerDecorator
System.Windows.Controls.ToolTip
逻辑树
System.Windows.Controls.Primitives.Popup
System.Windows.Controls.ToolTip
请注意:因为弹出有它自己的根所以它可能无法从主窗口的视觉或逻辑树访问。
Note: since popup has it's own root so it may not be accessible from main window's visual or logical tree.
为了找到刀尖弹出
我已经使用附加属性找到一个提示
I have used attached properties to find the popup for a tooltip
namespace CSharpWPF
{
public class ToolTipHelper : DependencyObject
{
public static bool GetIsEnabled(DependencyObject obj)
{
return (bool)obj.GetValue(IsEnabledProperty);
}
public static void SetIsEnabled(DependencyObject obj, bool value)
{
obj.SetValue(IsEnabledProperty, value);
}
// Using a DependencyProperty as the backing store for IsEnabled. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsEnabledProperty =
DependencyProperty.RegisterAttached("IsEnabled", typeof(bool), typeof(ToolTipHelper), new PropertyMetadata(false,OnEnable));
private static void OnEnable(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ToolTip t = d as ToolTip;
DependencyObject parent = t;
do
{
parent = VisualTreeHelper.GetParent(parent);
if(parent!=null)
System.Diagnostics.Debug.Print(parent.GetType().FullName);
} while (parent != null);
parent = t;
do
{
//first logical parent is the popup
parent = LogicalTreeHelper.GetParent(parent);
if (parent != null)
System.Diagnostics.Debug.Print(parent.GetType().FullName);
} while (parent != null);
}
}
}
XAML
xaml
<Button Content="Click me" ToolTip="Likes to be clicked">
<Button.Resources>
<Style TargetType="{x:Type ToolTip}" BasedOn="{StaticResource {x:Type ToolTip}}"
xmlns:l="clr-namespace:CSharpWPF">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="HasDropShadow" Value="True" />
<Setter Property="l:ToolTipHelper.IsEnabled" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToolTip}">
<StackPanel Background="Wheat" Height="200" Width="200">
<TextBlock x:Name="TxbTitle" FontSize="24" Text="ToolTip" Background="BurlyWood" />
<ContentPresenter />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Resources>
</Button>
我已经加入新创建的附加属性为工具提示风格< setter属性=L:ToolTipHelper.IsEnabledVALUE =真/>
从后面
Retrieve ToolTip instance from code behind
在事件中,你不能指定样式或XAML的样式模板,那么后面的代码是你的检索工具提示实例
In event you can not specify the style or template of style from xaml then code behind is your way to retrieve the tooltip instance
示例代码
Style style = new Style(typeof(ToolTip), (Style)this.FindResource(typeof(ToolTip)));
style.Setters.Add(new Setter(ToolTipHelper.IsEnabledProperty, true));
this.Resources.Add(typeof(ToolTip), style);
以上代码的工具提示创建一个样式对象,并增加了对 ToolTipHelper二传手。 IsEnabledProperty
并注入相同的样式窗口的资源
code above creates a style object for tooltip and adds a setter for ToolTipHelper.IsEnabledProperty
and inject the same style to the resources of the window
作为导致属性更改处理程序 OnEnable
将在 ToolTipHelper
来显示当过需要的工具提示类调用。而在处理器的依赖对象将是实际情况提示您可能进一步操纵。
as result the property changed handler OnEnable
will be invoked in the ToolTipHelper
class when ever the tooltip is required to be displayed. and the dependency object in the handler will be the actual tooltip instance which you may further manipulate.