取消WPF应用程序中的Unloaded事件

时间:2010-03-02 13:18:14

标签: c# .net wpf

我实现了一个WPF应用程序,它使用NavigationService在页面之间导航 当我从一个页面切换到另一个页面时,会为属于前一页面的每个图形元素引发Unloaded事件 有没有办法取消该事件而无法访问图形元素,只能访问容器?

3 个答案:

答案 0 :(得分:3)

由于Unloaded(和Loaded,就此而言)不是隧道事件,我认为没有办法在高层取消这个。

我很想知道你想要达到的目标。您是否正在释放与子项目相关的资源?您是否担心返回此页面并重新初始化资源的影响?如果是这样,也许应用程序缓存是存储它们的更好的地方,这样您就可以知道它们何时被初始化,它们的使用频率等等。这也可以为您提供一个集中的位置来清理缓存的资源。内存压力或您知道前面步骤中的资源无效的情况(例如,您已完成向导,因此您知道不需要与向导中先前步骤相关联的任何资源)。

或者,如果您正在寻找完全取消导航的机会,我相信您正在寻找导航事件。取消此事件应停止加载新资源并阻止当前页面更改。

- 添加有关缓存解决方案的信息(不适合评论)

我的第一个想法是,只有在您知道某些内容实际上是现实世界中的性能问题时,您才应该进行优化。如果这确实是一个问题,您可以创建一个单独的缓存对象,它存在于您的应用程序中以管理这些对象。我确信有一些我不知道的预构建解决方案,但是包含在Singeton对象中的字符串键的接口中的Dictionary对于简单的应用程序就足够了。然后,您可以通过简单的界面

访问它
CustomApplicationObjectCache[CACHE_KEY_CONSTANT_STRING] = new VisualBrush(...); //Or whatever type you have

但是,除非你正在处理一些非常重量级的对象或对象图,否则我怀疑缓存是否过度,可能会妨碍.NET为垃圾收集做正确的事情。我建议您对应用程序进行概要分析,看看这实际上是否存在性能问题。

答案 1 :(得分:2)

当PresentationSource断开连接时会触发

Unloaded,这是在导航到另一个页面之后。

WPF非常谨慎地确保在Unloaded已断开连接的每个控件上触发PresentationSource,因此阻止Unloaded触发图形元素的唯一方法是阻止PresentationSource被断开连接。有几种方法可以实现这一目标:

解决方案1:取消导航事件

实现此目的的一种方法是取消Navigating事件,强制用户停留在同一页面上。这当然会阻止PresentationSource断开连接,因此Unloaded事件不会触发。这可能是也可能不是可行的解决方案,具体取决于您的特定UI要求。

解决方案2:将您的元素置于导航框架之外

使用AdornerLayer可以使导航框外的控件看起来好像它们实际位于导航框内。由于导航框架外的可视树在导航时不会发生变化,因此PresentationSource永远不会与Adorner断开连接。

解决方案3:使用您自己的PresentationSource

如果必须完全阻止图形元素断开连接,则可以实现自己的PresentationSource。将您的图形元素放在自定义PresentationSource下,然后使用PresentationSource将它们绘制到真实DrawingContext上。如果希望控件进行交互,您可能还需要重定向输入事件。请注意,此解决方案非常复杂,只能作为最后的手段使用。

答案 2 :(得分:0)

我在这里回答了类似的问题。我确切地知道你想要达到的目的。这总是对我有用:

private void UserControl_Unloaded(object sender, RoutedEventArgs e)
        {
            if (ConditionsMet) { e.Handled = true; }

            //if ConditionsMet the Unloaded event will be set to true henceforth keeping your control in the VisualTree - your control does not Unload