我正在监听页面的加载事件。该事件首先触发,然后所有子元素都会触发它们的加载事件。我需要一个在所有子元素都加载完成时触发的事件。这种事件存在吗?
我明白您的意思。在WPF中,我也想要一个开箱即用的解决方案。
有时候您需要在所有子控件加载完成后执行某些代码。
将以下代码放入父控件的构造函数中:
Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(() => {code that should be executed after all children are loaded} ));
迄今为止帮了我几次。
Loaded
是在所有子元素Initialized
之后触发的事件。据我所知,没有AfterLoad
事件。如果可以的话,请将子元素的逻辑移动到Initialized
事件中,然后Loaded
事件会在它们全部初始化后发生。
请参阅MSDN - 对象生命周期事件。
其中一个选项(当内容呈现时):
this.LayoutUpdated += OnLayoutUpdated;
private void OnLayoutUpdated(object sender, EventArgs e)
{
if (!isInitialized && this.ActualWidth != 0 && this.ActualHeight != 0)
{
isInitialized = true;
// Logic here
}
};
在你想要等待的 xaml
组件内,加入一个加载事件 Loaded="MyControl_Loaded"
,如下所示:
<Grid Name="Main" Loaded="Grid_Loaded"...>
<TabControl Loaded="TabControl_Loaded"...>
<MyControl Loaded="MyControl_Loaded"...>
...
在你的代码
中
bool isLoaded;
private void MyControl_Loaded(object sender, RoutedEventArgs e)
{
isLoaded = true;
}
然后,在事件触发器内,如果要执行某些操作但在所有组件正确加载之前就已经触发,请添加if(!isLoaded) return;
。
private void OnButtonChanged(object sender, RoutedEventArgs e)
{
if(!isLoaded) return;
... // code that must execute on trigger BUT after load
}
由于大多数情况下数据决定是否加载特定子项到VisualTree中(例如DataTemplate中的UI元素),因此WPF无法提供那种事件。
因此,如果您能更清楚地解释您的场景,我们可以找到特定于该场景的解决方案。
最终我按照这些方式做了一些事情...你的结果可能会有所不同。
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)();
}