【问题标题】:Is there a "All Children loaded" event in WPFWPF 中是否存在“加载所有子项”事件
【发布时间】:2009-02-19 21:20:47
【问题描述】:

我正在监听页面的加载事件。该事件首先触发,然后所有的孩子触发他们的加载事件。我需要一个在所有孩子都加载后触发的事件。存在吗?

【问题讨论】:

    标签: c# .net wpf


    【解决方案1】:

    我听到了。为此,我还缺少 WPF 中的开箱即用解决方案。

    有时您希望在加载所有子控件后执行一些代码。

    把this放在父控件的构造函数中

    Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(() => {code that should be executed after all children are loaded} ));
    

    到目前为止帮了我几次。

    【讨论】:

    • 像魅力一样工作。谢谢!
    • 效果很好。恕我直言,WPF UserControl API 应该包含一个 PostLoaded 事件,该事件在加载所有控件并复制此实现后触发。
    【解决方案2】:

    Loaded 是在所有孩子都成为Initialized 之后触发的事件。据我所知,没有AfterLoad 事件。如果可以的话,将孩子的逻辑移到Initialized事件中,然后Loaded会在它们全部初始化后发生。

    MSDN - Object Lifetime Events

    【讨论】:

    • 如果一个答案不正确,怎么会有 7 个赞成票? Buckly 的答案,只有 2 票,效果很好。
    • @FrederikPrijck 一个答案是正确的并不意味着另一个答案不是。这个答案 is 正确,很有用,并且正是我所需要的——我在孩子的 Loaded 处理程序中做的事情比在其 Initialized 处理程序中应该做的事情。事实上,巴克利的回答说“为此在 WPF 中缺少一个开箱即用的解决方案”同意这个答案。并查看 Jobi 的回答,这表明在某些情况下 Buckey 的破解是不够的。
    • 我在哪里说只有一个答案是正确的?这个答案对我不起作用,但这与只保留一个答案是正确的完全不同。但是已经有一段时间了,所以我不知道细节。
    • @FrederikPrijck 因为 和投票给你的 5 个人不正确? The Loaded event and the Initialized event, MSDN
    • 如果父项需要获取子项的确切渲染大小,则此方法不起作用。
    【解决方案3】:

    【讨论】:

      【解决方案4】:

      WPF 无法提供这种事件,因为大多数时候 Data 决定是否将特定子项加载到 VisualTree(例如 DataTemplate 中的 UI 元素)

      因此,如果您能更清楚地解释您的场景,我们就能找到特定的解决方案。

      【讨论】:

        【解决方案5】:

        我遇到了同样的问题。 @configurator 是对的,如果您遇到此问题,那么我相信这是因为您的子元素有问题。在我的情况下,自定义用户控件所在的子元素。我错误地初始化了它们。我修复了用户控件,一切正常

        【讨论】:

          【解决方案6】:

          其中一个选项(呈现内容时):

          this.LayoutUpdated += OnLayoutUpdated;

          private void OnLayoutUpdated(object sender, EventArgs e)
                      {
                          if (!isInitialized && this.ActualWidth != 0 && this.ActualHeight != 0)
                          {
                              isInitialized = true;
                              // Logic here
                          }
                      };
          

          【讨论】:

            【解决方案7】:

            我最终按照这些思路做了一些事情.. 你的里程可能会有所不同。

            void WaitForTheKids(Action OnLoaded)
            {
              // After your children have been added just wait for the Loaded
              // event to fire for all of them, then call the OnLoaded delegate
            
              foreach (ContentControl child in Canvas.Children)
              {
                child.Tag = OnLoaded; // Called after children have loaded
                child.Loaded += new RoutedEventHandler(child_Loaded);
              }
            }
            internal void child_Loaded(object sender, RoutedEventArgs e)
            {
              var cc = sender as ContentControl;
              cc.Loaded -= new RoutedEventHandler(child_Loaded);
            
              foreach (ContentControl ctl in Canvas.Children)
              {
                if (!ctl.IsLoaded)
                {
                  return;
                }
              }
              ((Action)cc.Tag)();
            }
            

            【讨论】:

              猜你喜欢
              • 2019-04-01
              • 1970-01-01
              • 2014-04-04
              • 1970-01-01
              • 2010-10-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-03-21
              相关资源
              最近更新 更多