silverlight的元素基类FrameworkElement有事件LayoutUpdated,该事件表示元素发生布局变化后出发,什么是 布局发生变化,比较多了,比如尺寸的变化width height,或者位置的变化 left top,甚至被其他元素遮挡关系的变化,都算是布局变化。
这里主要说这个时间响应处理时的参数Sender,Sender不陌生,所有事件函数都有这个参数,表示触发该事件的对象。
Silverlight的元素LayoutUpdated事件中,Sender比较特殊,如果你实现一段代码来响应这个事件,往往会发现Sender是Null,如果不佳判断的使用它,将出现未初始化的异常错误。
来看看微软官方关于FrameworkElement.LayoutUpdated的说明
FrameworkElement.LayoutUpdated 事件
Silverlight
当 Silverlight 可视化树的布局更改时发生。
备注
LayoutUpdated 是序列中准备好进行交互的控件之前要发生的最后一个对象生存期事件。但是,由于以下多种原因,在对象生存期期间也可能在运行时发生 LayoutUpdated:属性更改、窗口大小调整或显式请求(UpdateLayout 或 ApplyTemplate)。在树中的所有可能 SizeChanged 事件引发完成后,引发 LayoutUpdated 事件。
在 WPF 中,此事件是路由事件,它实际上位于 UIElement 而非 FrameworkElement 上。在 Silverlight 中,此事件不是路由事件,而是使用 EventArgs(而非 RoutedEventArgs)的标准 CLR 事件。
当附加处理程序的对象不必更改其下的可视化树中的任何内容时,可能发生 LayoutUpdated。例如,假设一个包含两个元素的布局容器。如果第一个对象更改了一个强制执行新布局的属性,两个对象都会引发 LayoutUpdated,因为第二个对象可能会被重新定位,即使其自己的子布局不发生更改也是如此。
当您处理 LayoutUpdated 时,不要依赖于 sender 值。对于 LayoutUpdated,sender 始终为 null,而无论在何处附加处理程序。这是为了防止处理程序将任何含义分配给 sender,例如,暗示正是由特定元素在可视化树之外引发了此事件。相反,LayoutUpdated 暗示总体 Silverlight 可视化树中的某些内容已发生变化,树中任何位置的每个特定对象都具有处理此事件的选项。Silverlight 版本的 LayoutUpdated 在一定程度上具有此行为,以保持 WPF 兼容性。
上文是微软MSDN对silverlight FrameworkElement.LayoutUpdated的说明片段,留意一下其中我红色标注的一句,微软也布局变化事件的Sender参数进行了 特别说明,不要去使用这个Sender,因为布局变化实在太频繁太复杂影响也太广泛,呵呵,以至于不好处理他的触发对象是谁了。
我做了个 sl应用,大致是一个容器里有若干图标可以通过拖动改变位置,并且我想再拖动图标改变位置时对其父容器大小进行改变以能够完全容纳所有图标。本来我是自己 扩展了一个事件,来表示图标位置变化,后发现silverlight本来就有FrameworkElement.LayoutUpdated事件,就改用 这个事件响应处理,可发现异常不断,因为元素之间相互交叉相互影响触发的布局变化事件太多了,往往造成循环触发而异常抛出。并且致命的是这个sender 还往往会给Null值,不能根据其来判断我挪动了哪个图标。最终无果,只有还是使用自己实现的位置变化的事件。