2017-08-29 16 views
-1

我想實現「滾動以加載更多」功能。附加一個自定義綁定來檢查ScrollViewer verticalOffset屬性是否已更改。以下代碼用於在ListBox加載中註冊綁定。「ListenerOffset」屬性已通過「UserControl」登記

public static ScrollViewer scrollViewer; 
public static DependencyProperty offsetChangeListener; 
public static Binding binding; 

private void initScrollViewerMonitor(object sender, RoutedEventArgs e) 
{ 
    //get the ScrollViewer from the ListBox 
    scrollViewer = GetDescendantByType(accountHistoryList, typeof(ScrollViewer)) as ScrollViewer; 


    //attach to custom binding to check if ScrollViewer verticalOffset property has changed 
    if (binding == null || offsetChangeListener == null) 
    { 
     var binding = new Binding("VerticalOffset") { Source = scrollViewer }; 
     offsetChangeListener = DependencyProperty.RegisterAttached(
           "ListenerOffset", 
           typeof(object), 
           typeof(UserControl), 
           new PropertyMetadata(OnScrollChanged)); 
     scrollViewer.SetBinding(offsetChangeListener, binding); 
    } 
} 

但是,當第二次重新加載ListBox時,會出現以下錯誤。

System.ArgumentException: '' ListenerOffset '屬性已經 通過 「用戶控件」 註冊'。

我可以在卸載時取消註冊嗎?

+0

除此之外一個DependencyProperty場應該是靜態的,也有強制性的命名約定的ListenerOffset依賴屬性的支持字段應該被命名爲ListenerOffsetProperty。徹底閱讀[自定義依賴屬性](https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/custom-dependency-properties)和[附加屬性概述](https://docs.microsoft .COM/EN-US/DOTNET /框架/ WPF /高級/連接 - 屬性 - 概述)。 – Clemens

回答

-1

發生了什麼事情是依賴性屬性獲取多次註冊在同一名稱和所有者。依賴屬性旨在擁有一個所有者,並且應該是靜態實例化的。如果您沒有靜態實例化它們,則會嘗試爲每個控件實例註冊它們。

就頂你的DependencyProperty聲明靜態(不是內部函數)

public static DependencyProperty offsetChangeListener = DependencyProperty.RegisterAttached(
           "ListenerOffset", 
           typeof(object), 
           typeof(UserControl), 
           new PropertyMetadata(OnScrollChanged)); 

同時檢查「的typeof(用戶控件)」應該是實際控制而不是它的基礎class.The第三個參數RegisterAttached(ownerType)必須始終是宣佈財產的類。

-1

依賴屬性應該靜態分配,不應該基於實例。例外情況是告訴您該酒店已通過UserControl類型註冊。應使用設置的值在類中公共靜態只讀場的

依賴項屬性標識符。該標識符 隨後用於稍後引用依賴性屬性,用於操作 ,例如以編程方式設置其值或獲取元數據。 MSDN

現在我可以看到你檢查的附加屬性,但你正在檢查if(binding == null) { ... },但要定義var binding低了下去。 var ..正在創建一個不使用您的類變量binding的新變量binding。因此var binding is not equal to binding ...這可能與您的實例無關。

現在基本上你想要做的就是創建你的offsetChangeListener a static readonly等屬性。

static readonly DependencyProperty offsetChangeListener = DependencyProperty.RegisterAttached("ListenerOffset", 
                           typeof(object), 
                           typeof(UserControl), 
                           new PropertyMetadata(OnScrollChanged)); 

現在你需要追蹤無論您已經註冊綁定但是如果你只在init階段登記(即構造函數等),你可以確保只註冊一次。

private void initScrollViewerMonitor(object sender, RoutedEventArgs e) 
{ 
    var binding = new Binding("VerticalOffset") { Source = scrollViewer }; 
    scrollViewer.SetBinding(offsetChangeListener, binding); 
}