【问题标题】:WPF tree error when navigating back to former tab导航回前一个选项卡时出现 WPF 树错误
【发布时间】:2010-10-20 18:26:26
【问题描述】:

所以对于我的应用程序,我只加载了一个图像,然后在一个选项卡项的网格中。单击按钮后,我创建了一个带有关联代码的新选项卡项以加载其他内容。但是,在返回第一个选项卡时,我遇到了这个错误:

“在附加到新的父 Visual 之前,必须断开指定子与当前父 Visual 的连接。”

具体来说:

    public class VisualsHost : FrameworkElement
{

    DrawingVisual _square;

    public VisualsHost()
    {
        _square = new DrawingVisual();
        this.Loaded += new RoutedEventHandler(OnLoaded);
    }

    public void OnLoaded(object sender, RoutedEventArgs e)
    {

        AddVisualChild(_square);
        AddLogicalChild(_square);
    }

这只是我在主选项卡中用于我的内容的选择方块的容器。

所以我想知道,这里到底发生了什么,我将如何解决这个问题?

我的第一个标签中的内容的简要结构是:

tabcontrol> 停靠面板 ->listbox -> 网格(itemspanelcontainer 样式) -> listboxitems...

【问题讨论】:

    标签: wpf


    【解决方案1】:

    每次选择选项卡时都会调用 Loaded 事件,从而尝试再次添加 _square!

    Loaded 事件不一定只在第一次加载时调用一次 - 例如,如果您使用系统主题并更改了系统主题,则元素可能会再次加载,所有视觉元素都会重新加载。在您的情况下,视觉树以某种方式再次失效 - 可能是因为您对图像的绑定再次被读取(如果这是原因,将您的绑定也更改为 OneTime 可能是个好主意)。更多信息在这里:http://msdn.microsoft.com/en-us/library/ms754221.aspx 和这里:http://blogs.msdn.com/b/mikehillberg/archive/2006/09/19/loadedvsinitialized.aspx

    更新:来自上面第二个链接中的评论,适用于您的情况:

    “如果我可以添加加载和卸载 UI 元素时也会引发加载事件。这种情况是如果您在选项卡“A”中有一个名为“x”的按钮,当用户切换到选项卡时'B' 为 x 引发 UnLoaded 事件。当用户切换回选项卡 A 时,为 x 引发 Loaded 事件,但不是 Initialized 事件..."

    您应该能够在调试时通过断点确认是否确实如此。如果是:您可以使用标志来阻止事件执行任何操作或在事件运行后删除事件:

    public class VisualsHost : FrameworkElement
    {
      bool hasLoaded = false;
      DrawingVisual _square;
    
      public VisualsHost()
      {
        _square = new DrawingVisual();
        this.Loaded += new RoutedEventHandler(OnLoaded);
      }
    
      public void OnLoaded(object sender, RoutedEventArgs e)
      {
        if(!hasLoaded)
        {
          AddVisualChild(this._square);
          AddLogicalChild(this._square);
          this.hasLoaded = true;
          this.Loaded -= OnLoaded; // unnecessary if using the hasLoaded flag
        }
      }
    }
    

    【讨论】:

    • 主要问题是,当我转到那个新标签时会发生什么?是一棵新树被创造出来还是什么,而旧树被消灭了?显然旧的不是。对我来说,让 WPF 有内存来了解每个开关上前一个视觉/逻辑树的结构和状态更有意义。
    • 没有创建任何新内容 - 一个鲜为人知的事实:Loaded 事件不仅在第一次加载时被调用一次 - 例如,如果您使用系统主题并更改了系统主题,则可能会再次加载该元素所有视觉元素都被重新加载。在你的情况下,视觉树再次以某种方式失效 - 可能是因为你对图像的绑定被再次读取(如果这是原因,将你的绑定也更改为 OneTime 可能是个好主意)。更多信息在这里:msdn.microsoft.com/en-us/library/…
    • 在我自己了解到这一点后,我不得不添加检查,以确保我的 Loaded 事件处理程序只在我的代码中运行一次..
    【解决方案2】:

    或者如果您使用 KM 控件(您的网格?),您可能需要升级:http://social.msdn.microsoft.com/forums/en-US/wpf/thread/321f9721-ca38-41ca-b851-7667895d6d84

    【讨论】:

      猜你喜欢
      • 2012-01-22
      • 2012-04-30
      • 1970-01-01
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-18
      相关资源
      最近更新 更多