/// <summary>
        /// ResourceDictionaryUriProperty property changed handler.
        /// </summary>
        /// <param name="dependencyObject">FrameworkElement that changed its
        /// ResourceDictionaryUri.</param>
        /// <param name="eventArgs">Event arguments.</param>
        private static void OnResourceDictionaryUriPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs eventArgs)
        {
            FrameworkElement element = dependencyObject as FrameworkElement;

            if (element != null)
            {
                Uri value = (Uri)eventArgs.NewValue;
                ResourceDictionary resourceDictionary = null;
                if (value != null)
                {
                    try
                    {
                        resourceDictionary = Parse(value);
                        ImplicitStyleManager.SetExternalResourceDictionary(element, resourceDictionary);
                    }
                    catch (Exception)
                    {
                        element.ClearValue(ImplicitStyleManager.ExternalResourceDictionaryProperty);
                        throw;
                    }
                }
                else
                {
                    element.ClearValue(ImplicitStyleManager.ExternalResourceDictionaryProperty);
                }
            }
        }
        /// <summary>
        /// Retrieves or creates the merged style dictionary of an element.
        /// </summary>
        /// <param name="styledElement">A styled element.</param>
        /// <returns>The merged dictionary of the element.</returns>
        private static BaseMergedStyleDictionary GetMergedStyleDictionary(FrameworkElement styledElement)
        {
            Debug.Assert(styledElement != null, "styledElement cannot be null.");

            IList <FrameworkElement> ancestorsInclusive = styledElement.GetVisualAncestors().Append(styledElement).Reverse().ToList();

            IEnumerable <FrameworkElement> ancestorsTopToBottom = ancestorsInclusive;

            BaseMergedStyleDictionary initialDictionary = null;

            if (UseApplicationResources)
            {
                initialDictionary = new MergedStyleResourceDictionary(ApplicationExternalResourceDictionary ?? Application.Current.Resources);
            }
            else
            {
                FrameworkElement topLevelElement = ancestorsInclusive[0];
                initialDictionary = new MergedStyleResourceDictionary(ImplicitStyleManager.GetExternalResourceDictionary(topLevelElement) ?? topLevelElement.Resources);

                ancestorsTopToBottom = ancestorsInclusive.Skip(1);
            }

            BaseMergedStyleDictionary styleDictionary =
                ancestorsTopToBottom.Aggregate(
                    initialDictionary,
                    (dictionary, ancestor) => new MergedStyleResourceDictionary(ImplicitStyleManager.GetExternalResourceDictionary(ancestor) ?? ancestor.Resources)
            {
                Parent = dictionary
            });

            return(styleDictionary);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Load a theme from a resource stream.
        /// </summary>
        /// <param name="themeResourceStream">
        /// A resource stream containing the theme to load.
        /// </param>
        private void LoadTheme(Stream themeResourceStream)
        {
            Debug.Assert(themeResourceStream != null, "themeResourceStream should not be null!");

            // Load the theme
            using (Stream stream = themeResourceStream)
            {
                ResourceDictionary resources = ResourceParser.Parse(stream, true);
                ImplicitStyleManager.SetExternalResourceDictionary(this, resources);
            }
        }
        /// <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);
                }
            }
        }