【问题标题】:Navigating up the visual tree in WPF在 WPF 中向上导航可视化树
【发布时间】:2011-05-10 18:54:34
【问题描述】:

我在 DataTemplate 中显示了一张图片。我想更改单击图像时围绕我的图像的 DataTemplate 的样式。

它曾经像下面这样直接嵌套在堆栈面板中,因此我可以通过执行以下操作轻松获取父堆栈面板。

StackPanel sp = img.Parent as StackPanel;
<StackPanel Name="uxSessionImageItem" Style="{DynamicResource RotatorItemTemplateUnselectedStyle}" Loaded="uxSessionImageItem_Loaded" >
     <TextBlock Name="uxLabel"  Width="150" Text="{Binding SessionImageID}" Foreground="White" VerticalAlignment="Center"/>
     <Image MouseDown="ImagePanel_MouseDown" Name="uxImage" Style="{DynamicResource ItemTemplateImageStyle}" Source="{Binding ThumbPath}"/>
</StackPanel>   

我必须在图像和我需要找到的堆栈面板之间添加另一个堆栈面板和边框。我需要什么语法才能找到现在不是我父级的边框,也不是作为边框父级的堆栈面板,而是那个上方的堆栈面板?

<StackPanel Name="uxSessionImageItem" Style="{DynamicResource RotatorItemTemplateUnselectedStyle}" Loaded="uxSessionImageItem_Loaded" >
    <TextBlock Name="uxLabel"  Width="150" Text="{Binding SessionImageID}" VerticalAlignment="Center" Style="{DynamicResource ItemTemplateImageNumberStyle}"/>
    <StackPanel Name="uxSessionImageWrapper" Style="{DynamicResource RotatorItemImageWrapperStyle}" >
        <Border Name="uxImageBorder" Style="{DynamicResource ItemTemplateImageBorderStyle}">
            <Image MouseDown="ImagePanel_MouseDown" Name="uxImage" Style="{DynamicResource ItemTemplateImageStyle}" Source="{Binding ThumbPath}"/>
        </Border>
    </StackPanel>
</StackPanel>

【问题讨论】:

    标签: wpf


    【解决方案1】:

    CodeNaked 的回答很好,但我不喜欢那篇文章中的代码使用递归来完成这个简单的任务,所以这里有一个修改版本,它可以避免堆栈溢出(不确定 WPF 是否可以嵌套这么多,但值得冒险吗?)

    public static T FindParentOfType<T>(this DependencyObject child) where T : DependencyObject
    {
        DependencyObject parentDepObj = child;
        do
        {
            parentDepObj = VisualTreeHelper.GetParent(parentDepObj);
            T parent = parentDepObj as T;
            if (parent != null) return parent;
        }
        while (parentDepObj != null);
        return null;
    }
    

    【讨论】:

      【解决方案2】:

      您可以使用VisualTreeHelper 向上或向下导航可视化树。 Parent 属性是逻辑父级,这是不同的。这个解释更多here

      您可以使用此 Linq To Visual Tree 代码来使用 Linq 类型语句来遍历可视化树,但这最终会利用 VisualTreeHelper 类。或者,您可以构建像 this one 这样的扩展方法,以便更轻松地找到祖先(不一定是直接父母)。

      【讨论】:

        【解决方案3】:

        我真的不明白,如果您已经将 StackPanel 命名为 uxSessionImageItem,为什么不在代码中使用它来引用它?

        【讨论】:

        • 如果它在 DataTemplate 中,那么您不能通过这样的代码隐藏按名称访问。每次使用 DataTemplate 时,可能会有多个 StackPanel 实例。
        • 谢谢,错过了 DataTemplate 部分。
        【解决方案4】:

        img.Parent.Parent.Parent 是外部 StackPanel。

        (事实上,StackPanel 中有多个相同级别的元素,如果你沿着 VisualTree 往下走,这只是一个问题,向上总是很容易,因为每个元素只能有一个父元素。)

        编辑: 正如 CodeNaked 指出的 Parent 使用逻辑树,如果您寻找的只是相对引用,这应该不是问题。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-12-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多