我实现了一个WPF应用程序,它使用NavigationService在页面之间导航 当我从一个页面切换到另一个页面时,会为属于前一页面的每个图形元素引发Unloaded事件 有没有办法取消该事件而无法访问图形元素,只能访问容器?
答案 0 :(得分:3)
由于Unloaded(和Loaded,就此而言)不是隧道事件,我认为没有办法在高层取消这个。
我很想知道你想要达到的目标。您是否正在释放与子项目相关的资源?您是否担心返回此页面并重新初始化资源的影响?如果是这样,也许应用程序缓存是存储它们的更好的地方,这样您就可以知道它们何时被初始化,它们的使用频率等等。这也可以为您提供一个集中的位置来清理缓存的资源。内存压力或您知道前面步骤中的资源无效的情况(例如,您已完成向导,因此您知道不需要与向导中先前步骤相关联的任何资源)。
或者,如果您正在寻找完全取消导航的机会,我相信您正在寻找导航事件。取消此事件应停止加载新资源并阻止当前页面更改。
- 添加有关缓存解决方案的信息(不适合评论)
我的第一个想法是,只有在您知道某些内容实际上是现实世界中的性能问题时,您才应该进行优化。如果这确实是一个问题,您可以创建一个单独的缓存对象,它存在于您的应用程序中以管理这些对象。我确信有一些我不知道的预构建解决方案,但是包含在Singeton对象中的字符串键的接口中的Dictionary对于简单的应用程序就足够了。然后,您可以通过简单的界面
访问它CustomApplicationObjectCache[CACHE_KEY_CONSTANT_STRING] = new VisualBrush(...); //Or whatever type you have
但是,除非你正在处理一些非常重量级的对象或对象图,否则我怀疑缓存是否过度,可能会妨碍.NET为垃圾收集做正确的事情。我建议您对应用程序进行概要分析,看看这实际上是否存在性能问题。
答案 1 :(得分:2)
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