Search code examples
c#xamlwin-universal-appparent

How do I reach my parent-property from custom-panel


I use the custom panel from this article: Custom Itemspanel

The ItemsPanel is embedded inside an usercontrol like this:

<UserControl
    x:Class="CustomControls.LoopList"
    x:Name="LoopListControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:CustomControls"
    xmlns:ctrl="using:CustomControls.Controls"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:vm="using:CustomControls.ViewModel"
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="200">
    <ItemsControl ItemsSource="{Binding LoopListSource, ElementName=LoopListControl}" 
                    HorizontalAlignment="Center" VerticalAlignment="Stretch" Height="Auto" Width="{Binding ItemWidth, ElementName=LoopListControl}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <ctrl:LoopItemsPanel x:Name="LoopControl" Loaded="LoopControl_Loaded"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
</UserControl>

I'm modifying the custom-panel and need to get a dependency-property by the name of 'SelectedIndex' from the parent-usercontrol by the name 'LoopListControl'

This is the Live-Visual-Tree-Structure: Live-Visual-Tree-Structure:

What I tried so far for getting the SelectedIndex was this (inside the custom-panel) but the Parent is allways 'null':

public void SetToIndex()
{
    if (this.Children == null || this.Children.Count == 0)
        return;

    var rect = this.Children[0].TransformToVisual(this).TransformBounds(new Rect(0, 0, this.Children[0].DesiredSize.Width, this.Children[0].DesiredSize.Height));
    var selectedChild = this.Children[(Parent as LoopList).SelectedIndex];

    ScrollToSelectedIndex(selectedChild, rect);
}

Based on the Live-Visual-Tree-Structure I also tried this:

(((this.Parent as ContentControl).Parent as ItemsPresenter).Parent as ItemsControl).Parent as LoopList

And received the error: "Object reference not set to an instance of an object."

Do you have any idea how to get the value?


Solution

  • There is a method that allow you find the first parent of a given type for a control.

    public static T FindParent<T>(DependencyObject child) where T : DependencyObject
    {
        //get parent item
        DependencyObject parentObject = VisualTreeHelper.GetParent(child);
    
        //we've reached the end of the tree
        if (parentObject == null) return null;
    
        //check if the parent matches the type we're looking for
        T parent = parentObject as T;
        if (parent != null)
            return parent;
        else
            return FindParent<T>(parentObject);
    }
    

    Then you just have to call this method like this :

    LoopList parentLoopList = FindParent<LoopList>(theControlInWhichYouWantToFindTheParent);
    if (parentLoopList!= null)
       //Do your job
    

    I don't guarantee that you will not get the same exception but at least, if this method don't return what is expected or the method return null, it will be a good start to have look at what is going wrong.