2010-03-02 32 views
2

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

回答

3

由于卸载(和加载,对于这件事)不是隧道事件,我不认为有任何方法可以取消这个高层次。

我很好奇你试图达到什么目的。你是否释放与子项目相关的资源?您是否担心返回此页面并重新初始化资源的影响?如果是这样,可能应用程序缓存是一个更好的地方来存储它们,这样你就可以知道它们什么时候被初始化,它们被使用的频率等等。这也会给你一个集中的地方来清理缓存的资源内存压力或者您知道前面步骤的资源无效的情况(例如,您已完成向导,因此您知道不需要与向导中的早期步骤相关联的任何资源)。或者,如果您正在寻找完全取消导航的机会,我相信您正在寻找导航事件。取消此事件应该暂停加载新资源并防止当前页面发生更改。

大约缓存解决方案 - 增加信息(不适合在评论)

我首先想到的是,一旦你知道的东西实际上是在真实世界中的性能问题,你应该只优化。如果这确实是一个问题,那么可以创建一个驻留在应用程序中的单例缓存对象来管理这些对象。我确信有一些我没有意识到的预建解决方案,但包装在一个包含在Singeton对象中的字符串键的界面中的Dictionary对于一个简单的应用程序就足够了。然后,您可以通过一个简单的界面来访问它

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

除非你正在处理一些非常重量级的对象或对象的图形,不过,我怀疑缓存将是矫枉过正,并可能会得到在.NET的方式做垃圾收集的正确之处。我会建议分析你的应用程序,看看这是否是一个性能问题。

+0

你猜,我很担心返回到这个页面和重新初始化资源的影响。你能否向我解释一下你对应用程序缓存的意义? – 2010-03-02 15:10:05

2

Unloaded在PresentationSource断开连接时触发,这是在导航到另一个页面之后发生的。

WPF需要非常谨慎,以确保Unloaded上有其PresentationSource断开每个控制发射,这样可以防止Unloaded从射击你的图形元素的唯一途径是防止PresentationSource被断开。有几种方法来实现:

方案一:取消导航事件来完成这个

一种方法是取消Navigating事件,迫使用户留在同一页上。这当然会阻止PresentationSource被断开,因此Unloaded事件不会触发。这可能或可能不是一个可行的解决方案,具体取决于您的特定用户界面要求。

解决方案2:家长导航框架

之外的元素使用的AdornerLayer有可能有导航框架外控看起来好像他们导航框架内实际上。由于导航框外的可视化树在导航时不会改变,所以PresentationSource永远不会与Adorner断开连接。

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

如果你必须绝对避免你的图形元素,从以往被断开,你可以实现自己的PresentationSource。将图形元素放在您的自定义PresentationSource下,然后使用DrawingContext将它们绘制到实际的PresentationSource上。如果您希望控件进行交互,您可能还需要重定向输入事件。请注意,这个解决方案相当复杂,只能作为最后的手段使用。

+0

你能解释你的第二个解决方案多一点,并提供一些示例代码? – SepehrM 2013-12-05 13:53:54

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