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) { // Debug.WriteLine($"--- RULE {rule.SelectorString} ----"); if (rule.SelectorType == SelectorType.VisualTree) { treeNodeProvider.Switch(SelectorType.VisualTree); if (visualTree == null) { visualTree = treeNodeProvider.GetDomElement(startFrom ?? styleResourceReferenceHolder); visualTree.XamlCssStyleSheets.Clear(); visualTree.XamlCssStyleSheets.Add(styleSheet); } root = visualTree; } else { treeNodeProvider.Switch(SelectorType.LogicalTree); if (logicalTree == null) { if (!treeNodeProvider.IsInTree(startFrom ?? styleResourceReferenceHolder)) { continue; } 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> >() .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(); var matchedElementTypes = matchedNodes .Select(x => x.Element.GetType()) .Distinct() .ToList(); foreach (var matchingNode in matchedNodes) { var element = matchingNode.Element; var oldMatchingStyles = dependencyPropertyService.GetMatchingStyles(element) ?? new string[0]; var resourceKey = nativeStyleService.GetStyleResourceKey(styleSheet.Id, element.GetType(), rule.SelectorString); var newMatchingStyles = oldMatchingStyles.Concat(new[] { resourceKey }).Distinct() .Select(x => new { key = x, selector = new Selector { Value = x.Split('{')[1] } }) .OrderBy(x => x.selector.IdSpecificity) .ThenBy(x => x.selector.ClassSpecificity) .ThenBy(x => x.selector.SimpleSpecificity) .ToArray(); var newMatchingStylesStrings = newMatchingStyles.Select(x => x.key).ToArray(); // Debug.WriteLine($"'{rule.SelectorString}' {GetPath(matchingNode)}: " + string.Join("|", newMatchingStylesStrings)); dependencyPropertyService.SetMatchingStyles(element, newMatchingStylesStrings); if (requiredStyleInfos.Any(x => x.Rule == rule && x.MatchedType == element.GetType()) == false) { requiredStyleInfos.Add(new StyleMatchInfo { Rule = rule, MatchedType = element.GetType() }); } } } return(requiredStyleInfos); }
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); }
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> >() .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(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); }