3

I have a class which extends Canvas in WPF.

This class is placed in a ScrollViewer.

Without passing a specific reference to the ScrollViewer into the Canvas, I want to find the ScrollViewer which contains the Canvas from within the Canvas itself.

The Parent property of the class which extends Canvas is null, and every attempt to use the VisualTreeHelper just returns null as well.

I have attempted to find the visual ancestor using VisualTreeHelper.GetParent(this), however the parent property is null.

As the ExtendedCanvas will be used in multiple instances, I would like it to be able to resolve its containing ScrollViewer without the need to specifically reference the ScrollViewer in either code behind or in XAML.

I realise that I could add a dependency propery in the ExtendedCanvas and create a binding in the XAML, however I would like the component to work by simply dropping it into a container.

Similarly, I would not be averse to placing the ScrollViewer onto a panel of some sort, then placing my ExtendedCanvas within it, so that my component uses that panel as its lowermost containing element.

What is puzzling me is that as I understand it, the VisualTreeHelper will navigate the entire visual tree for the running application. It seems that either my assumption is entirely wrong, or it can only navigate downwards from the specified component.

Is this possible to achieve without the above approaches?

Example Code:

cs -

public class ExtendedCanvas:Canvas {

    //I wish to automatically populate this scroll viewer
    //reference to the instance of the scrollviwer which contains
    //this ExtendedCanvas instance
    private ScrollViewer _containingScrollViewer = null;

}

xaml -

    <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" >
        <local:ExtendedCanvas x:Name="extendedCanvas" />
    </ScrollViewer>
4

1 回答 1

3

您可以像这样找到它的父级:

    public ExtendedCanvas()
    {
        //it hasn't been added to its parent yet
        Loaded += ExtendedCanvas_Loaded;
    }

    private void ExtendedCanvas_Loaded(object sender, RoutedEventArgs e)
    {
        //now it is added to its parent
        _containingScrollViewer  = Parent as ScrollViewer;
    }
于 2018-07-27T15:34:26.913 回答