从 SurfaceListBox 中的 class 访问 public 方法

Accessing a public method from a class inside a SurfaceListBox

我已经创建了一个 WPF 解决方案,如 https://msdn.microsoft.com/en-us/library/ff727730.aspx 中所述。该解决方案将使用 SurfaceListBox 为我提供一个连续列表。这工作正常,没有问题。

现在我想单击图像并向任意方向移动 X 像素。

所以,我创建了事件 MainSurfaceListBox_OnSelectionChanged 并将其添加到 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>

MainWindow.xaml.cs

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

现在,从 MainWindow.xaml.cs 我正在尝试 运行 方法 LoopPanelVertical.LineUp()。我的问题是我无法找到访问此方法或 LoopPanelVertical.

中的任何 public 方法的方法
namespace ContinuousList
{
    public class LoopPanelVertical : Panel, ISurfaceScrollInfo
    {
        ...
        public void LineUp()
        {
             ScrollContent(1);
        }
    }
}

请帮助我了解实现该目标的必要条件吗?谢谢!

为了调用(非静态)class 的方法,您需要引用该 class 的实例。您可以设置 LoopPanelVertical class 的 Namex:Name 属性,然后使用该名称引用它:

<ControlTemplate>
    <s:SurfaceScrollViewer
        VerticalScrollBarVisibility="Disabled"
        HorizontalScrollBarVisibility="Hidden"
        CanContentScroll="true">
        <l:LoopPanelVertical x:Name="Panel" IsItemsHost="True"/>
    </s:SurfaceScrollViewer>
</ControlTemplate>

...

private void MainSurfaceListBox_OnSelectionChanged(object sender, 
    SelectionChangedEventArgs e)
{
    Panel.LineUp();
}

刚刚使用子元素找到了答案:

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