我想实现"滚动以加载更多"功能。附加自定义绑定以检查ScrollViewer verticalOffset属性是否已更改。以下代码用于在ListBox加载上注册绑定。
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'财产已经 由" UserControl"。'
注册
我可以在卸载时取消注册吗?
答案 0 :(得分:-1)
发生了什么是依赖属性在同一名称和所有者下多次注册。依赖属性旨在拥有单个所有者,并且应该静态实例化。如果您没有静态实例化它们,则会尝试为每个控件实例注册它们。
将DependencyProperty声明设置为静态(不在函数内部)
public static DependencyProperty offsetChangeListener = DependencyProperty.RegisterAttached(
"ListenerOffset",
typeof(object),
typeof(UserControl),
new PropertyMetadata(OnScrollChanged));
同时检查" typeof(UserControl)"应该是实际控件而不是它的基类.RegisterAttached(ownerType)的第三个参数必须始终是声明属性的类。
答案 1 :(得分:-1)
依赖属性应该静态分配,不应该基于实例。例外情况是告诉您该属性已经由UserControl
类型注册。
应该用于设置值的依赖项属性标识符 在您的班级中公共静态只读字段。那个标识符是 然后用于引用依赖属性以用于操作 例如以编程方式设置其值或获取元数据。 MSDN
现在,我可以看到您正在检查附加的媒体资源,但是您正在查看if(binding == null) { ... }
,但是您正在定义var binding
更低版本。 var ..
正在创建一个新变量binding
而不使用您的类变量binding
。因此var binding is not equal to binding
...这可能与您的实例无关。
现在基本上你要做的就是创建你的offsetChangeListener
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);
}