什么时候XAML(UWP)GridView完全加载?

时间:2016-11-01 03:05:27

标签: c# xaml uwp uwp-xaml

<GridView 
    Name="Slider"
    ItemsSource="{Binding Node.Contents}"
    Loaded="SliderLoaded"
    .../>

ViewModel初始化是异步的,这就是我设置绑定中引用的Node属性的地方。

这是项目面板的样式:

<Setter Property="ItemsPanel">
    <Setter.Value>
        <ItemsPanelTemplate>
            <ItemsStackPanel Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </Setter.Value>
</Setter>

关于代码背后:

private async void SliderLoaded(object sender, RoutedEventArgs e)
{
    // I get a null reference exception trying to access the GridView scrollViewer here

    await Task.Delay(150); // [hack] wait a bit for the view tree and binding to be ready

    // the scrollViewer is accessible after the delay
}

这就是我访问ScrollViewer的方式:

public static ScrollViewer GetScrollViewer(this DependencyObject element)
{
    if (element is ScrollViewer)
    {
        return (ScrollViewer)element;
    }

    for (var i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++)
    {
        var child = VisualTreeHelper.GetChild(element, i);

        var result = GetScrollViewer(child);
        if (result != null)
            return result;
    }

    return null;
}

阅读文档和其他SO答案,“加载”事件处理程序会像所有子视图和绑定的创建和可用位置一样,但正如您在评论中看到的那样,它无效。

我也尝试了DataContextChanged事件处理程序,结果相同。

我如何或何时可以100%确定网格scrollViewer和项目到位?

2 个答案:

答案 0 :(得分:1)

您没有指定如何获取GridView的ScrollViewer。我假设您正在使用VisualTreeHelper这样做?

这对我有用:

<GridView Loaded="GridView_Loaded"/>
private void GridView_Loaded(object sender, RoutedEventArgs e)
{
    var scrollViewer = ((UIElement)sender)
                           .ChildrenBreadthFirst()
                           .OfType<ScrollViewer>()
                           .First();
}
public static class Extensions
{
    public static IEnumerable<UIElement> ChildrenBreadthFirst(this UIElement element)
    {
        var queue = new Queue<UIElement>();
        queue.Enqueue(element);

        while (queue.Count > 0)
        {
            element = queue.Dequeue();
            var count = VisualTreeHelper.GetChildrenCount(element);

            for (var i = 0; i < count; i++)
            {
                var child = (UIElement)VisualTreeHelper.GetChild(element, i);
                yield return child;
                queue.Enqueue(child);
            }
        }
    }
}

答案 1 :(得分:0)

很抱歉这个混乱。我的代码工作正常,我没有意识到。事情就是我有一个函数让ScrollView和其他东西找到项目并进行动画滚动。 ScrollView就在那里,但是TaskCompletionSource中包含的代码中的其他部分却默默地失败了。

无论如何,所有这一切的重点是以编程方式滚动GridView,当我用ItemsStackPanel中的StackPanel替换ItemsPanelTemplate时,所有问题都消失了。

很抱歉打扰并感谢大家。