// Callback on visiting each node in the descendency during a broadcast event private static bool OnBroadcastCallback(DependencyObject d, BroadcastEventData data, bool visitedViaVisualTree) { DependencyObject root = data.Root; RoutedEvent routedEvent = data.RoutedEvent; List<DependencyObject> eventRoute = data.EventRoute; if (FrameworkElement.DType.IsInstanceOfType(d)) { // If this is a FrameworkElement FrameworkElement fe = (FrameworkElement)d; if (fe != root && routedEvent == FrameworkElement.LoadedEvent && fe.UnloadedPending != null) { // If there is a pending Unloaded event wait till we've broadcast // that event before we can fire the new Loaded event. fe.FireLoadedOnDescendentsInternal(); } else if (fe != root && routedEvent == FrameworkElement.UnloadedEvent && fe.LoadedPending != null) { // If there is a pending Loaded event abort it because we are now // being Unloaded. RemoveLoadedCallback(fe, fe.LoadedPending); } else { if (fe != root) { if (routedEvent == FrameworkElement.LoadedEvent && fe.LoadedPending != null) { // If there is a pending Loaded event abort it because we are now // being Loaded. RemoveLoadedCallback(fe, fe.LoadedPending); } else if (routedEvent == FrameworkElement.UnloadedEvent && fe.UnloadedPending != null) { // If there is a pending Unloaded event abort it because we are now // being Unloaded. RemoveUnloadedCallback(fe, fe.UnloadedPending); } } // If element has handlers fire the event and continue to walk down the tree if (fe.SubtreeHasLoadedChangeHandler) { // We cannot assert this condition here for the following reason. // If the [Un]LoadedHandler is added to the current node after the parent // for this node has been [Un]Loaded but before the current node has been [Un]Loaded // (example: within the [Un]Loaded handler for the parent), then the IsLoaded // cache on the current node has been updated to match that of the parent, // and this Assert will be violated. See BroadcastEventHelper.UpdateHasHandlerFlag // for further description. // Debug.Assert(IsLoaded == [false/true], // "Element should have been [Un]loaded before it is [Un]Loaded back again"); fe.IsLoadedCache = (routedEvent == FrameworkElement.LoadedEvent); eventRoute.Add(fe); // Continue walk down subtree return true; } } } else { // If this is a FrameworkContentElement FrameworkContentElement fce = (FrameworkContentElement)d; if (fce != root && routedEvent == FrameworkElement.LoadedEvent && fce.UnloadedPending != null) { // If there is a pending Unloaded event wait till we've broadcast // that event before we can fire the new Loaded event. fce.FireLoadedOnDescendentsInternal(); } else if (fce != root && routedEvent == FrameworkElement.UnloadedEvent && fce.LoadedPending != null) { // If there is a pending Loaded event abort it because we are now // being Unloaded. RemoveLoadedCallback(fce, fce.LoadedPending); } else { if (fce != root) { if (routedEvent == FrameworkElement.LoadedEvent && fce.LoadedPending != null) { // If there is a pending Loaded event abort it because we are now // being Loaded. RemoveLoadedCallback(fce, fce.LoadedPending); } else if (routedEvent == FrameworkElement.UnloadedEvent && fce.UnloadedPending != null) { // If there is a pending Unloaded event abort it because we are now // being Unloaded. RemoveUnloadedCallback(fce, fce.UnloadedPending); } } // If element has handlers fire the event and continue to walk down the tree if (fce.SubtreeHasLoadedChangeHandler) { // We cannot assert this condition here for the following reason. // If the [Un]LoadedHandler is added to the current node after the parent // for this node has been [Un]Loaded but before the current node has been [Un]Loaded // (example: within the [Un]Loaded handler for the parent), then the IsLoaded // cache on the current node has been updated to match that of the parent, // and this Assert will be violated. See BroadcastEventHelper.UpdateHasHandlerFlag // for further description. // Debug.Assert(IsLoaded == [false/true], // "Element should have been [Un]loaded before it is [Un]Loaded back again"); fce.IsLoadedCache = (routedEvent == FrameworkElement.LoadedEvent); eventRoute.Add(fce); // Continue walk down subtree return true; } } } // Stop walk down subtree return false; }
// Callback on visiting each node in the descendency during a broadcast event private static bool OnBroadcastCallback(DependencyObject d, BroadcastEventData data, bool visitedViaVisualTree) { DependencyObject root = data.Root; RoutedEvent routedEvent = data.RoutedEvent; List <DependencyObject> eventRoute = data.EventRoute; if (FrameworkElement.DType.IsInstanceOfType(d)) { // If this is a FrameworkElement FrameworkElement fe = (FrameworkElement)d; if (fe != root && routedEvent == FrameworkElement.LoadedEvent && fe.UnloadedPending != null) { // If there is a pending Unloaded event wait till we've broadcast // that event before we can fire the new Loaded event. fe.FireLoadedOnDescendentsInternal(); } else if (fe != root && routedEvent == FrameworkElement.UnloadedEvent && fe.LoadedPending != null) { // If there is a pending Loaded event abort it because we are now // being Unloaded. RemoveLoadedCallback(fe, fe.LoadedPending); } else { if (fe != root) { if (routedEvent == FrameworkElement.LoadedEvent && fe.LoadedPending != null) { // If there is a pending Loaded event abort it because we are now // being Loaded. RemoveLoadedCallback(fe, fe.LoadedPending); } else if (routedEvent == FrameworkElement.UnloadedEvent && fe.UnloadedPending != null) { // If there is a pending Unloaded event abort it because we are now // being Unloaded. RemoveUnloadedCallback(fe, fe.UnloadedPending); } } // If element has handlers fire the event and continue to walk down the tree if (fe.SubtreeHasLoadedChangeHandler) { // We cannot assert this condition here for the following reason. // If the [Un]LoadedHandler is added to the current node after the parent // for this node has been [Un]Loaded but before the current node has been [Un]Loaded // (example: within the [Un]Loaded handler for the parent), then the IsLoaded // cache on the current node has been updated to match that of the parent, // and this Assert will be violated. See BroadcastEventHelper.UpdateHasHandlerFlag // for further description. // Debug.Assert(IsLoaded == [false/true], // "Element should have been [Un]loaded before it is [Un]Loaded back again"); fe.IsLoadedCache = (routedEvent == FrameworkElement.LoadedEvent); eventRoute.Add(fe); // Continue walk down subtree return(true); } } } else { // If this is a FrameworkContentElement FrameworkContentElement fce = (FrameworkContentElement)d; if (fce != root && routedEvent == FrameworkElement.LoadedEvent && fce.UnloadedPending != null) { // If there is a pending Unloaded event wait till we've broadcast // that event before we can fire the new Loaded event. fce.FireLoadedOnDescendentsInternal(); } else if (fce != root && routedEvent == FrameworkElement.UnloadedEvent && fce.LoadedPending != null) { // If there is a pending Loaded event abort it because we are now // being Unloaded. RemoveLoadedCallback(fce, fce.LoadedPending); } else { if (fce != root) { if (routedEvent == FrameworkElement.LoadedEvent && fce.LoadedPending != null) { // If there is a pending Loaded event abort it because we are now // being Loaded. RemoveLoadedCallback(fce, fce.LoadedPending); } else if (routedEvent == FrameworkElement.UnloadedEvent && fce.UnloadedPending != null) { // If there is a pending Unloaded event abort it because we are now // being Unloaded. RemoveUnloadedCallback(fce, fce.UnloadedPending); } } // If element has handlers fire the event and continue to walk down the tree if (fce.SubtreeHasLoadedChangeHandler) { // We cannot assert this condition here for the following reason. // If the [Un]LoadedHandler is added to the current node after the parent // for this node has been [Un]Loaded but before the current node has been [Un]Loaded // (example: within the [Un]Loaded handler for the parent), then the IsLoaded // cache on the current node has been updated to match that of the parent, // and this Assert will be violated. See BroadcastEventHelper.UpdateHasHandlerFlag // for further description. // Debug.Assert(IsLoaded == [false/true], // "Element should have been [Un]loaded before it is [Un]Loaded back again"); fce.IsLoadedCache = (routedEvent == FrameworkElement.LoadedEvent); eventRoute.Add(fce); // Continue walk down subtree return(true); } } } // Stop walk down subtree return(false); }