开发者

Navigating up the visual tree in WPF

I have an image being displayed in a DataTemplate. I want to change the style of the DataTemp开发者_如何学Clate that's surrounding my image when the image is clicked on.

It used to be nested directly in a stackpanel like the following so I could get the parent stackpanel easily by doing the following.

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>   

I had to add another stackpanel and a border in between the image and the stack panel that I need to find. What syntax do I need to find not the border that is now my parent nor the stackpanel that's the border's parent but the stackpanel above that one?

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


CodeNaked answer is good, but i don't like the fact that the code in that article use recursion to accomplish this simple task, so here's a modified version, which can possibly avoid a stack overflow (not sure WPF can be nested so much, but is it worth risking ?)

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


You can use VisualTreeHelper to navigate up or down the visual tree. The Parent property is the logical parent, which is different. This is explained more here.

You can use this Linq To Visual Tree code to use Linq type statements to traverse the visual tree, but this ultimately leverage the VisualTreeHelper class. Or you can build extension methods like this one to make finding ancestors (not necessarily direct parents) easier.


I don't really understand that if you already named your StackPanel uxSessionImageItem, why don't you use it to reference it in your code?


img.Parent.Parent.Parent is the outer StackPanel.

(The fact that there are multiple elements at the same level in a StackPanel is only a problem if you go down the VisualTree, up is always easy as every element can only have one parent.)

Edit: As CodeNaked pointed out Parent uses the logical tree, this should not be a problem if all you look for is a relative reference.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜