示例#1
0
        private StyleSheet GetStyleSheet(IDomElement <TDependencyObject> domElement)
        {
            var element = GetStyleSheetHolder(domElement)?.Element;

            if (element == null)
            {
                return(null);
            }

            return(dependencyPropertyService.GetStyleSheet(element));
        }
示例#2
0
        private static void SetupStyleInfo(
            IDomElement <TDependencyObject> domElement,
            StyleSheet styleSheet,
            Dictionary <TDependencyObject, StyleUpdateInfo> styleUpdateInfos,
            ISwitchableTreeNodeProvider <TDependencyObject> switchableTreeNodeProvider,
            IDependencyPropertyService <TDependencyObject, TStyle, TDependencyProperty> dependencyPropertyService,
            INativeStyleService <TStyle, TDependencyObject, TDependencyProperty> nativeStyleService,
            bool styleChanged,
            bool styleSheetRemoved)
        {
            var styleUpdateInfo = "get styleUpdateInfo".Measure(() => domElement.StyleInfo = domElement.StyleInfo ?? (styleUpdateInfos.ContainsKey(domElement.Element) ? styleUpdateInfos[domElement.Element] :
                                                                                                                      GetNewStyleUpdateInfo(domElement, dependencyPropertyService, nativeStyleService)));

            var styleSheetFromDom = "GetStyleSheet".Measure(() => dependencyPropertyService.GetStyleSheet(domElement.Element));

            if (styleSheetFromDom != null &&
                styleSheetFromDom != styleSheet)
            {
                // another stylesheet's domelement
                SetupStyleInfo(domElement, styleSheetFromDom, styleUpdateInfos, switchableTreeNodeProvider, dependencyPropertyService, nativeStyleService, styleChanged, false);
                return;
            }

            "set styleUpdateInfo values".Measure(() =>
            {
                if (!styleSheetRemoved)
                {
                    styleUpdateInfo.CurrentStyleSheet = styleSheet;
                }

                if (styleChanged)
                {
                    styleUpdateInfo.OldMatchedSelectors = new List <string>();
                }
                styleUpdateInfo.CurrentMatchedSelectors.Clear();
                styleUpdateInfo.DoMatchCheck |= switchableTreeNodeProvider.CurrentSelectorType;

                styleUpdateInfos[domElement.Element] = styleUpdateInfo;
            });

            "fill DomElement".Measure(() =>
            {
                object a;
                "ClassList".Measure(() => a    = domElement.ClassList);
                "Id".Measure(() => a           = domElement.Id);
                "TagName".Measure(() => a      = domElement.TagName);
                "NamespaceUri".Measure(() => a = domElement.AssemblyQualifiedNamespaceName);
                //"HasAttribute".Measure(() => a = domElement.HasAttribute("Name"));

                /*// a = domElement.Parent;
                 */
            });

            foreach (var child in domElement.ChildNodes)
            {
                SetupStyleInfo(child, styleSheet, styleUpdateInfos, switchableTreeNodeProvider, dependencyPropertyService, nativeStyleService, styleChanged, styleSheetRemoved);
            }
        }
示例#3
0
        public void NewElement(TDependencyObject sender)
        {
            if (sender == null)
            {
                return;
            }

            var parent = GetStyleSheetParent(sender as TDependencyObject);

            if (parent == null)
            {
                return;
            }

            EnqueueNewElement(
                parent,
                dependencyPropertyService.GetStyleSheet(parent),
                sender);
        }
示例#4
0
        public void NewElement(TDependencyObject sender)
        {
            if (sender == null)
            {
                return;
            }

            var parent = GetStyleSheetParent(sender as TDependencyObject);

            if (parent == null)
            {
                return;
            }

            /*if (dependencyPropertyService.GetInitialStyle(sender) == null)
             * {
             *  dependencyPropertyService.SetInitialStyle(sender, nativeStyleService.GetStyle(sender));
             * }*/
            EnqueueNewElement(
                parent,
                dependencyPropertyService.GetStyleSheet(parent),
                sender);
        }
示例#5
0
        private static void SetupStyleInfo(
            IDomElement <TDependencyObject, TDependencyProperty> domElement,
            StyleSheet styleSheet,
            Dictionary <TDependencyObject, StyleUpdateInfo> styleUpdateInfos,
            ITreeNodeProvider <TDependencyObject, TDependencyProperty> treeNodeProvider,
            IDependencyPropertyService <TDependencyObject, TStyle, TDependencyProperty> dependencyPropertyService,
            INativeStyleService <TStyle, TDependencyObject, TDependencyProperty> nativeStyleService,
            bool styleChanged,
            bool styleSheetRemoved, SelectorType type)
        {
            if (!domElement.IsReady)
            {
                return;
            }

            var styleUpdateInfo = domElement.StyleInfo = domElement.StyleInfo ?? (styleUpdateInfos.ContainsKey(domElement.Element) ? styleUpdateInfos[domElement.Element] :
                                                                                  GetNewStyleUpdateInfo(domElement, dependencyPropertyService, nativeStyleService));

            styleUpdateInfos[domElement.Element] = styleUpdateInfo;

            var styleSheetFromDom = dependencyPropertyService.GetStyleSheet(domElement.Element);

            if (styleSheetFromDom != null &&
                styleSheetFromDom != styleSheet)
            {
                // another stylesheet's domelement
                SetupStyleInfo(domElement, styleSheetFromDom, styleUpdateInfos, treeNodeProvider, dependencyPropertyService, nativeStyleService, styleChanged, false, type);
                return;
            }

            if (!styleSheetRemoved)
            {
                styleUpdateInfo.CurrentStyleSheet = styleSheet;
            }

            if (styleChanged)
            {
                styleUpdateInfo.OldMatchedSelectors = new LinkedHashSet <ISelector>();
            }
            styleUpdateInfo.CurrentMatchedSelectors.Clear();
            styleUpdateInfo.CurrentMatchedResourceKeys.Clear();
            styleUpdateInfo.DoMatchCheck |= type;

            var children = type == SelectorType.VisualTree ? domElement.ChildNodes : domElement.LogicalChildNodes;

            foreach (var child in children)
            {
                SetupStyleInfo(child, styleSheet, styleUpdateInfos, treeNodeProvider, dependencyPropertyService, nativeStyleService, styleChanged, styleSheetRemoved, type);
            }
        }
示例#6
0
        private static StyleSheet GetStyleSheetFromTree(IDomElement <TDependencyObject, TDependencyProperty> domElement,
                                                        IDependencyPropertyService <TDependencyObject, TStyle, TDependencyProperty> dependencyPropertyService)
        {
            var        current    = domElement;
            StyleSheet styleSheet = null;

            while (current != null &&
                   (styleSheet = dependencyPropertyService.GetStyleSheet(current.Element)) == null)
            {
                current = current.Parent;
            }

            return(styleSheet);
        }
示例#7
0
        public BaseCss(IDependencyPropertyService <TDependencyObject, TUIElement, TStyle, TDependencyProperty> dependencyPropertyService,
                       ITreeNodeProvider <TDependencyObject> treeNodeProvider,
                       IStyleResourcesService applicationResourcesService,
                       INativeStyleService <TStyle, TDependencyObject, TDependencyProperty> nativeStyleService,
                       string defaultCssNamespace,
                       IMarkupExtensionParser markupExpressionParser,
                       Action <Action> uiInvoker)
        {
            this.dependencyPropertyService   = dependencyPropertyService;
            this.treeNodeProvider            = treeNodeProvider;
            this.applicationResourcesService = applicationResourcesService;
            this.nativeStyleService          = nativeStyleService;
            this.markupExpressionParser      = markupExpressionParser;
            this.uiInvoker = uiInvoker;

            CssParser.Initialize(defaultCssNamespace);
            StyleSheet.GetParent     = parent => treeNodeProvider.GetParent((TDependencyObject)parent);
            StyleSheet.GetStyleSheet = treeNode => dependencyPropertyService.GetStyleSheet((TDependencyObject)treeNode);
        }
示例#8
0
        private List <StyleMatchInfo> UpdateMatchingStyles(TUIElement styleResourceReferenceHolder, StyleSheet styleSheet, TUIElement startFrom)
        {
            var requiredStyleInfos = new List <StyleMatchInfo>();
            IDomElement <TDependencyObject> root = null;

            IDomElement <TDependencyObject> visualTree  = null;
            IDomElement <TDependencyObject> logicalTree = null;

            foreach (var rule in styleSheet.Rules)
            {
                if (rule.SelectorType == SelectorType.VisualTree)
                {
                    if (visualTree == null)
                    {
                        visualTree = treeNodeProvider.GetDomElement(startFrom ?? styleResourceReferenceHolder);
                        visualTree.XamlCssStyleSheets.Clear();
                        visualTree.XamlCssStyleSheets.Add(styleSheet);
                    }

                    root = visualTree;
                }
                else
                {
                    if (logicalTree == null)
                    {
                        logicalTree = treeNodeProvider.GetDomElement(startFrom ?? styleResourceReferenceHolder);
                        logicalTree.XamlCssStyleSheets.Clear();
                        logicalTree.XamlCssStyleSheets.Add(styleSheet);
                    }

                    root = logicalTree;
                }

                // apply our selector
                var matchedNodes = root.QuerySelectorAllWithSelf(rule.SelectorString)
                                   .Where(x => x != null)
                                   .Cast <IDomElement <TDependencyObject> >()
                                   .Where(x => treeNodeProvider.GetParent(x.Element) != null) // workaround WPF: somehow dom-tree is out of sync with UI-tree!?!
                                   .ToList();

                var otherStyleElements = matchedNodes
                                         .Where(x =>
                {
                    var parent = GetStyleSheetParent(x.Element);
                    // parent happens to be null if class was changed by binding
                    if (parent == null)
                    {
                        return(true);
                    }
                    var elementStyleSheet = dependencyPropertyService.GetStyleSheet(parent);
                    return(elementStyleSheet != null && elementStyleSheet != styleSheet);
                }).ToList();

                matchedNodes = matchedNodes.Except(otherStyleElements).ToList();

                // Debug.WriteLine($"matchedNodes: ({matchedNodes.Count}) " + string.Join(", ", matchedNodes.Select(x => x.Id)));

                var matchedElementTypes = matchedNodes
                                          .Select(x => x.Element.GetType())
                                          .Distinct()
                                          .ToList();

                // Debug.WriteLine($"Matched Types: ({matchedElementTypes.Count}) " + string.Join(", ", matchedElementTypes.Select(x => x.Name)));

                foreach (var matchingNode in matchedNodes)
                {
                    var element = matchingNode.Element;

                    var matchingStyles = dependencyPropertyService.GetMatchingStyles(element) ?? new string[0];

                    var resourceKey = nativeStyleService.GetStyleResourceKey(styleSheet.Id, element.GetType(), rule.SelectorString);

                    dependencyPropertyService.SetMatchingStyles(element, matchingStyles.Concat(new[] { resourceKey }).Distinct().ToArray());

                    if (requiredStyleInfos.Any(x => x.Rule == rule && x.MatchedType == element.GetType()) == false)
                    {
                        requiredStyleInfos.Add(new StyleMatchInfo
                        {
                            Rule        = rule,
                            MatchedType = element.GetType()
                        });
                    }
                }
            }

            return(requiredStyleInfos);
        }