エロリジェクトで有名なしんじさんが引っ張って更新の方法をBlogに書かれてました。
ただ、この方法だとUIの仮想化が働かないような気がするんだけどどうだろう?ということで、これとは別にアプローチで頑張ってみようと思いました。
結果ダメでした
ListViewのVisualTreeからScrollViewerをひっぱってきて、そのコンテンツの移動量を見てやってやろうと思ったら、なぜか下にひっぱったときに0になってしまう…。なので、3秒間以上つまんでたら更新するようにしてみました。(BehaviorのPullToRefreshedイベントが発行される)
やりきれない思い。
using Microsoft.Xaml.Interactivity; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using Windows.Foundation; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Media; namespace App13 { [TypeConstraint(typeof(ListView))] public class PullToRefreshBehavior : DependencyObject, IBehavior { private ListView TargetObject { get; set; } public DependencyObject AssociatedObject { get { return this.TargetObject; } } public event EventHandler PullToRefreshed; private void OnPullToRefreshed() { var h = this.PullToRefreshed; if (h != null) { h(this, EventArgs.Empty); } } public void Attach(DependencyObject associatedObject) { this.TargetObject = (ListView)associatedObject; this.TargetObject.Loaded += (_, __) => { var startTime = DateTime.Now; var viewer = VisualTreeUtils.FindVisualTreeChild<ScrollViewer>(this.TargetObject); var target = (FrameworkElement)viewer.Content; target.LayoutUpdated += (___, ____) => { var point = target.TransformToVisual(this.TargetObject).TransformPoint(new Point(0, 0)); Debug.WriteLine("({0}, {1})", point.X, point.Y); if (point.Y >= 0 && (DateTime.Now - startTime).TotalMilliseconds > 3000) { this.OnPullToRefreshed(); } startTime = DateTime.Now; }; }; } public void Detach() { } } static class VisualTreeUtils { public static T FindVisualTreeChild<T>(FrameworkElement root) where T : FrameworkElement { Debug.WriteLine("{0}", root.GetType()); foreach(var current in GetChildren(root).Where(c => c != null).OfType<FrameworkElement>()) { var findTarget = current as T; if (findTarget != null) { return findTarget; } var found = FindVisualTreeChild<T>(current); if (found != null) { return found; } } return null; } private static IEnumerable<FrameworkElement> GetChildren(FrameworkElement root) { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(root); i++) { yield return VisualTreeHelper.GetChild(root, i) as FrameworkElement; } } } }