/// <summary> /// This method propagates the styles in the resources associated with /// a framework element to its descendents. This results in a /// style inheritance that mimics WPF's behavior. /// </summary> /// <param name="element">The element that will have its styles /// propagated to its children.</param> /// <param name="recurse">Whether to recurse over styled elements that /// are set to OneTime and have already been styled.</param> private static void PropagateStyles(FrameworkElement element, bool recurse) { BaseMergedStyleDictionary initialDictionary = GetMergedStyleDictionary(element); // Create stream of elements and their base merged style // dictionaries by traversing the logical tree. IEnumerable <Tuple <FrameworkElement, BaseMergedStyleDictionary> > elementsToStyleAndDictionaries = FunctionalProgramming.TraverseDepthFirst( new Tuple <FrameworkElement, BaseMergedStyleDictionary>(element, initialDictionary), (elementAndDictionary) => elementAndDictionary .First .GetLogicalChildrenDepthFirst() .Select(childElement => new Tuple <FrameworkElement, BaseMergedStyleDictionary>( childElement, new MergedStyleResourceDictionary( ImplicitStyleManager.GetExternalResourceDictionary(childElement) ?? childElement.Resources, elementAndDictionary.Second))), (elementAndDictionary) => recurse || (ImplicitStyleManager.GetApplyMode(elementAndDictionary.First) != ImplicitStylesApplyMode.OneTime || !ImplicitStyleManager.GetHasBeenStyled(elementAndDictionary.First))); foreach (Tuple <FrameworkElement, BaseMergedStyleDictionary> elementToStyleAndDictionary in elementsToStyleAndDictionaries) { FrameworkElement elementToStyle = elementToStyleAndDictionary.First; BaseMergedStyleDictionary styleDictionary = elementToStyleAndDictionary.Second; bool styleApplied = false; if (elementToStyle.Style == null || GetStyle(elementToStyle) == elementToStyle.Style) { Style style = styleDictionary[GetStyleKey(elementToStyle)]; if (style != null) { SetStyle(elementToStyle, style); styleApplied = true; } } if (ImplicitStyleManager.GetApplyMode(elementToStyle) == ImplicitStylesApplyMode.OneTime && (VisualTreeHelper.GetChildrenCount(elementToStyle) > 0 || styleApplied)) { ImplicitStyleManager.SetHasBeenStyled(elementToStyle, true); } } }
/// <summary> /// ApplyModeProperty property changed handler. /// </summary> /// <param name="dependencyObject">FrameworkElement that changed its /// ApplyMode.</param> /// <param name="eventArgs">Event arguments.</param> private static void OnApplyModePropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs eventArgs) { FrameworkElement element = dependencyObject as FrameworkElement; if (element == null) { throw new ArgumentNullException("dependencyObject"); } ImplicitStylesApplyMode oldMode = (ImplicitStylesApplyMode)eventArgs.OldValue; ImplicitStylesApplyMode newMode = (ImplicitStylesApplyMode)eventArgs.NewValue; ImplicitStyleManager.SetHasBeenStyled(element, false); EventHandler eventHandler = ImplicitStyleManager.GetLayoutUpdatedHandler(element); // If element is automatically styled (once or always) attach event // handler. if ((newMode == ImplicitStylesApplyMode.Auto || newMode == ImplicitStylesApplyMode.OneTime) && oldMode == ImplicitStylesApplyMode.None) { if (eventHandler == null) { eventHandler = (sender, args) => { ImplicitStyleManager.PropagateStyles(element, false); }; ImplicitStyleManager.SetLayoutUpdatedHandler(element, eventHandler); element.LayoutUpdated += eventHandler; } } else if ((oldMode == ImplicitStylesApplyMode.Auto || oldMode == ImplicitStylesApplyMode.OneTime) && newMode == ImplicitStylesApplyMode.None) { if (eventHandler != null) { element.LayoutUpdated -= eventHandler; ImplicitStyleManager.SetLayoutUpdatedHandler(element, null); } } }