在 WPF 的 ScrollViewer 控件中有 ScrollChanged 事件,到了 Silverlight 就沒有此事件了。經常會有需要使用此事件去驅動一些功能的實現,例如延遲加載。網上也流傳了一種使用監聽 VSM(Visual State Manager) 實現的方法(見這里),但是其方法有點過於復雜,並且效率低下。所以這里放出一種簡單的實現 ScrollChanged 事件的方法。
第一步:當然是找到你所需要增加此功能的頁面的后台代碼;
第二步:在為其增加一個事件
public event EventHandler VerticalScrollChanged;
第三步:在此頁面的構造函數中增加
this.SetBinding(//綁定
DependencyProperty.RegisterAttached("VerticalOffset",//注冊一個附加屬性
typeof(double),//這個屬性的類型是 double
this.GetType(),//需要注冊到自己
new PropertyMetadata((d, e) =>//元數據,注冊變化時的事件
{
if (VerticalScrollChanged != null)//如果有注冊,則驅動它
VerticalScrollChanged(this, EventArgs.Empty);
})),
new Binding("VerticalOffset") { Source = this.scrollViewer });//綁定的源和路徑
第四步:你就可以隨意的在某處注冊 VerticalScrollChanged 事件了。
注意一點,這里假設你所需要監聽的 ScrollViewer 已經命名為 “scrollViewer ”,並且只需要監聽垂直方向的滾動。
如果你感興趣,還可以將此方法封裝成一個新控件,直接調用。或者你可以將 WPF 中此事件完整的實現:ScrollChangedEventArgs。
好了,下面的代碼演示如何在即將滾動到底部的時候再次加載數據:
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
this.SetBinding(
DependencyProperty.RegisterAttached("VerticalOffset",
typeof(double),
this.GetType(),
new PropertyMetadata((d, e) =>
{
if (VerticalScrollChanged != null)
VerticalScrollChanged(this, EventArgs.Empty);
})),
new Binding("VerticalOffset") { Source = this.scrollViewer });
}
public event EventHandler VerticalScrollChanged;
private void button1_Click(object sender, RoutedEventArgs e)
{
Random rnd = new Random();
for (int i = 0; i < 40; i++)
{
items.Items.Add(new MyClass { A = rnd.Next(), B = rnd.Next() });
}
}
private void button2_Click(object sender, RoutedEventArgs e)
{
scrollViewer.ScrollToVerticalOffset(0.0);
items.Items.Clear();
}
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
this.VerticalScrollChanged += (ss, ee) =>
{
if (scrollViewer.ViewportHeight + scrollViewer.VerticalOffset > scrollViewer.ExtentHeight - scrollViewer.ViewportHeight * 3)
{
button1_Click(null, null);
}
};
}
public class MyClass
{
public int A { get; set; }
public int B { get; set; }
}
}
