Search code examples
c#wpflistboxselectionchanged

Accessing a public method from a class inside a SurfaceListBox


I've created a WPF Solution as described on https://msdn.microsoft.com/en-us/library/ff727730.aspx. This solution will provide me a continuous list using a SurfaceListBox. This is working ok, with no issues.

Now I'd like click on a image and move X pixels, in any direction.

So, I created the event MainSurfaceListBox_OnSelectionChanged and added that to MainWindow.xaml:

<Window x:Class="ContinuousList.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:s="http://schemas.microsoft.com/surface/2008"
        xmlns:l="clr-namespace:ContinuousList"
        Title="ContinuousList" Height="640" Width="800">
    <Grid>

        <s:SurfaceListBox Name="MainSurfaceListBox"
                          SelectionChanged="MainSurfaceListBox_OnSelectionChanged">
            <s:SurfaceListBox.ItemTemplate>
                <DataTemplate>
                    <Image Source="{Binding}" Width="270"/>
                </DataTemplate>
            </s:SurfaceListBox.ItemTemplate>
            <s:SurfaceListBox.Template>
                <ControlTemplate>
                    <s:SurfaceScrollViewer
                        VerticalScrollBarVisibility="Disabled"
                        HorizontalScrollBarVisibility="Hidden"
                        CanContentScroll="true">
                        <l:LoopPanelVertical IsItemsHost="True"/>
                    </s:SurfaceScrollViewer>
                </ControlTemplate>
            </s:SurfaceListBox.Template>
        </s:SurfaceListBox>

    </Grid>
</Window>

and inside MainWindow.xaml.cs

private void MainSurfaceListBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    //trying to call a public method from LoopPanelVertical
}

Now, from MainWindow.xaml.cs I'm trying to run the method LoopPanelVertical.LineUp(). My issue is that I cannot find a way to access this method, or any public method from LoopPanelVertical.

namespace ContinuousList
{
    public class LoopPanelVertical : Panel, ISurfaceScrollInfo
    {
        ...
        public void LineUp()
        {
             ScrollContent(1);
        }
    }
}

Would please help me in understanding what it necessary to achieve that? Thanks!


Solution

  • Just found an answer for that using the child element:

     private void MainSurfaceListBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                var listBox = sender as SurfaceListBox;
                if (listBox == null) return;
                var childElement = FindChild(listBox, i => i as LoopPanelVertical);
                childElement.LineUp();
            }
    
            static T FindChild<T>(DependencyObject obj, Func<DependencyObject, T> pred) where T : class
            {
                var childrenCount = VisualTreeHelper.GetChildrenCount(obj);
                for (var i = 0; i < childrenCount; i++)
                {
                    var dependencyObject = VisualTreeHelper.GetChild(obj, i);
                    var foo = pred(dependencyObject);
                    return foo ?? FindChild(dependencyObject, pred);
                }
                return null;
            }