在逻辑或可视树中查找工具提示弹出窗口

时间:2014-07-05 21:17:11

标签: c# wpf

假设我有一个ToolTip,其格式在XAML中指定,如下所示:

<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>

鉴于我有Button的引用且ToolTip正在显示,我怎样才能找到Popup的{​​{1}}(之后会查找其视觉效果)孩子,例如ToolTip)?

更新

基于pushpraj's回答,我能够抓住(完整)可视树,它看起来像这样:

TxbTitle

我可以在这里找到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
然而,

pushpraj的回答是基于我可以掌握System.Windows.Controls.Primitives.Popup System.Windows.Controls.ToolTip System.String 实例。我得到的只是ToolTipButton属性返回字符串Button.ToolTip,而不是"Likes to be clicked"实例。

更具体地说,问题是,当我得到{{1}时,我能以某种方式获得ToolTip ToolTip吗? }}

(疯狂的想法:有没有办法枚举所有开放的Popup?)

1 个答案:

答案 0 :(得分:8)

ToolTip是一种承载工具提示内容的Popup

由于Popup托管在一个单独的窗口中,因此它拥有自己的逻辑和可视树

以下信息是工具提示的可视和逻辑树

视觉树

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

注意:由于弹出窗口具有自己的根,因此可能无法从主窗口的可视或逻辑树访问它。

查找工具提示的弹出窗口

我使用附加属性来查找工具提示的弹出窗口

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

<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 Property="l:ToolTipHelper.IsEnabled" Value="True"/>

从后面的代码中检索ToolTip实例

如果您无法从xaml指定样式的样式或模板,那么代码隐藏是您检索工具提示实例的方法

示例代码

    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添加了一个setter,并为窗口的资源注入了相同的样式

结果,当需要显示工具提示时,将在OnEnable类中调用属性更改处理程序ToolTipHelper。并且处理程序中的依赖项对象将是您可能进一步操作的实际工具提示实例。