ストアアプリでListBoxを引っ張って更新

スマホとかでよく見る例のアレです。

まずはXAML側。引っ張って更新したいListBoxをScrollViewerの中に配置します。

<Grid>
    <ScrollViewer
        x:Name="parentScrollViewer"
        SizeChanged="parentScrollViewer_SizeChanged"
        VerticalScrollBarVisibility="Hidden"
        ZoomMode="Disabled">
        <ListBox x:Name="listbox" LayoutUpdated="listbox_LayoutUpdated">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Border Height="100" Width="400" Background="Green">
                        <TextBlock Text="{Binding}"/>
                    </Border>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </ScrollViewer>
</Grid>

次にC#側。 LayoutUpdateでListBoxのscrollViewerに対する相対座標を取得、0より大きければ更新処理を行います

public sealed partial class MainPage : Page
{
    ObservableCollection<int> source = new ObservableCollection<int>(Enumerable.Range(0, 2));
    public MainPage()
    {
        this.InitializeComponent();

        this.listbox.ItemsSource = source;
    }

    private void parentScrollViewer_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        listbox.Height = e.NewSize.Height;
    }

    DateTime startTime;
    private void listbox_LayoutUpdated(object sender, object e)
    {
        var point = listbox.TransformToVisual(parentScrollViewer).TransformPoint(new Point(0, 0));

        if (point.Y > 0 && (DateTime.Now - startTime).TotalMilliseconds > 500)
        {
            source.Add(source.Max() + 1);
        }
        startTime = DateTime.Now;
    }
}

これでListBoxを下にしばらく引っ張って離すとitemが1件増えます