public static void OnAutoScrollToEndChanged(DependencyObject s, DependencyPropertyChangedEventArgs e)
{
/* ... */
var scrollToEndHandler = new NotifyCollectionChangedEventHandler((sender, args) => // 수정
{
if (listBox.Items.Count > 0)
{
object lastItem = listBox.Items[listBox.Items.Count - 1];
listBoxItems.MoveCurrentTo(lastItem);
listBox.ScrollIntoView(lastItem);
}
});
if (isAutoScroll)
{
source.CollectionChanged += scrollToEndHandler; // A
}
else
{
source.CollectionChanged -= scrollToEndHandler; //B
}
}
https://michlg.wordpress.com/2010/01/17/listbox-automatically-scroll-to-bottom/
此代码由上层URL引用。
A(scrollToEndHandler)和B(scrollToEndHandler)在函数中。
更改“ AutoScrollToEndProperty”后,将始终调用“ OnAutoScrollToEndChanged”。
我想知道这些是否相同。谢谢。
最佳答案
如果您的问题基本上是,“取消订阅在这里确实有效吗?”从理论上讲,答案是特定于C#编译器实现的。
实际上,lambda表达式的主体不会捕获任何局部变量,但是会捕获this
(通过引用listBox
)...因此我希望编译器生成一个包含以下内容的实例方法: lambda表达式中的代码主体。
如果在同一个目标上多次调用该方法(即this
引用相同的对象),则我希望scrollToEndHandler
每次都是不同但相等的委托-换句话说,它将创建一个新的委托每个调用中的对象(如果lambda表达式未捕获任何东西,则可能不会,并且可以实现为静态方法并缓存了委托)...但是事件订阅/取消订阅仍将起作用,因为委托是相等(对于相同的方法,指的是相同的目标)。
如果lambda表达式引用方法中的任何局部变量,则事件处理将不起作用,因为编译器将通过包含相关变量和委托代码的方法的单独嵌套类捕获这些局部变量,并调用每个方法OnAutoScrollToEndChanged
的值将创建该嵌套类的新实例,从而导致不平等的委托。
就像我说的那样,所有这些都是特定于实现的……最好将代码移到单独的实例方法中,以使其更清楚地起作用。