private static CreateStyleDictionaryFromDeclarationBlockResult <TDependencyProperty> CreateStyleDictionaryFromDeclarationBlock( CssNamespaceCollection namespaces, StyleDeclarationBlock declarationBlock, Type matchedType, TDependencyObject dependencyObject, CssTypeHelper <TDependencyObject, TDependencyProperty, TStyle> cssTypeHelper) { var result = new CreateStyleDictionaryFromDeclarationBlockResult <TDependencyProperty>(); foreach (var styleDeclaration in declarationBlock) { var propertyInfo = cssTypeHelper.GetDependencyPropertyInfo(namespaces, matchedType, styleDeclaration.Property); if (propertyInfo == null) { continue; } try { var propertyValue = cssTypeHelper.GetPropertyValue(propertyInfo.DeclaringType, dependencyObject, propertyInfo.Name, styleDeclaration.Value, propertyInfo.Property, namespaces); result.PropertyStyleValues[propertyInfo.Property] = propertyValue; } catch { result.Errors.Add($"Cannot get property-value for '{styleDeclaration.Property}' with value '{styleDeclaration.Value}'!"); } } return(result); }
public BaseCss(IDependencyPropertyService <TDependencyObject, TStyle, TDependencyProperty> dependencyPropertyService, ITreeNodeProvider <TDependencyObject, TDependencyProperty> treeNodeProvider, IStyleResourcesService applicationResourcesService, INativeStyleService <TStyle, TDependencyObject, TDependencyProperty> nativeStyleService, string defaultCssNamespace, IMarkupExtensionParser markupExpressionParser, Action <Action> uiInvoker, ICssFileProvider fileProvider) { this.dependencyPropertyService = dependencyPropertyService; this.treeNodeProvider = treeNodeProvider; this.applicationResourcesService = applicationResourcesService; this.nativeStyleService = nativeStyleService; this.markupExpressionParser = markupExpressionParser; this.uiInvoker = uiInvoker; this.cssTypeHelper = new CssTypeHelper <TDependencyObject, TDependencyProperty, TStyle>(markupExpressionParser, dependencyPropertyService); CssParser.Initialize(defaultCssNamespace, fileProvider); StyleSheet.GetParent = parent => treeNodeProvider.GetParent((TDependencyObject)parent, SelectorType.VisualTree); StyleSheet.GetStyleSheet = treeNode => dependencyPropertyService.GetStyleSheet((TDependencyObject)treeNode); }
private static void GenerateStyles(StyleSheet styleSheet, IDictionary <TDependencyObject, StyleUpdateInfo> styleMatchInfos, IStyleResourcesService applicationResourcesService, IDependencyPropertyService <TDependencyObject, TStyle, TDependencyProperty> dependencyPropertyService, INativeStyleService <TStyle, TDependencyObject, TDependencyProperty> nativeStyleService, CssTypeHelper <TDependencyObject, TDependencyProperty, TStyle> cssTypeHelper) { applicationResourcesService.EnsureResources(); foreach (var styleMatchInfoKeyValue in styleMatchInfos) { var styleMatchInfo = styleMatchInfoKeyValue.Value; var matchedElementType = styleMatchInfo.MatchedType; for (var i = 0; i < styleMatchInfo.CurrentMatchedSelectors.Count; i++) { var selector = styleMatchInfo.CurrentMatchedSelectors.ElementAt(i); var resourceKey = styleMatchInfo.CurrentMatchedResourceKeys.ElementAt(i); if (applicationResourcesService.Contains(resourceKey)) { // Debug.WriteLine($"GenerateStyles: Already contains '{s}' ({matchedElementType.Name})"); continue; } // Debug.WriteLine($"GenerateStyles: Generating '{s}' ({matchedElementType.Name})"); var rule = styleMatchInfo.CurrentStyleSheet.Rules.Where(x => x.SelectorString == selector.Value).First(); CreateStyleDictionaryFromDeclarationBlockResult <TDependencyProperty> result = null; try { result = CreateStyleDictionaryFromDeclarationBlock( styleSheet.Namespaces, rule.DeclarationBlock, matchedElementType, (TDependencyObject)styleSheet.AttachedTo, cssTypeHelper); var propertyStyleValues = result.PropertyStyleValues; foreach (var error in result.Errors) { // Debug.WriteLine($@" ERROR (normal) in Selector ""{rule.SelectorString}"": {error}"); styleSheet.AddError($@"ERROR in Selector ""{rule.SelectorString}"": {error}"); } var nativeTriggers = rule.DeclarationBlock.Triggers .Select(x => nativeStyleService.CreateTrigger(styleSheet, x, styleMatchInfo.MatchedType, (TDependencyObject)styleSheet.AttachedTo)) .ToList(); var initalStyle = dependencyPropertyService.GetInitialStyle(styleMatchInfoKeyValue.Key); if (initalStyle != null) { var subDict = nativeStyleService.GetStyleAsDictionary(initalStyle as TStyle); foreach (var item in subDict) { // only set not-overridden properties if (!propertyStyleValues.ContainsKey(item.Key)) { propertyStyleValues[item.Key] = item.Value; } } var triggers = nativeStyleService.GetTriggersAsList(initalStyle as TStyle); nativeTriggers.InsertRange(0, triggers); } //Debug.WriteLine(" Values: " + string.Join(", ", propertyStyleValues.Select(x => ((dynamic)x.Key).PropertyName + ": " + x.Value.ToString()))); var style = nativeStyleService.CreateFrom(propertyStyleValues, nativeTriggers, matchedElementType); applicationResourcesService.SetResource(resourceKey, style); // Debug.WriteLine("Finished generate Style " + resourceKey); } catch (Exception e) { // Debug.WriteLine($@" ERROR (exception) in Selector ""{rule.SelectorString}"": {e.Message}"); styleSheet.AddError($@"ERROR in Selector ""{rule.SelectorString}"": {e.Message}"); } } } }
public static void Render( List <RenderInfo <TDependencyObject> > copy, ITreeNodeProvider <TDependencyObject, TDependencyProperty> treeNodeProvider, IDependencyPropertyService <TDependencyObject, TStyle, TDependencyProperty> dependencyPropertyService, INativeStyleService <TStyle, TDependencyObject, TDependencyProperty> nativeStyleService, IStyleResourcesService applicationResourcesService, CssTypeHelper <TDependencyObject, TDependencyProperty, TStyle> cssTypeHelper) { try { applicationResourcesService.BeginUpdate(); RemoveOldStyleObjects(copy, nativeStyleService, applicationResourcesService); SetAttachedToToNull(copy, dependencyPropertyService, treeNodeProvider, nativeStyleService); SetAttachedToToNewStyleSheet(copy, dependencyPropertyService, treeNodeProvider, nativeStyleService); var styleUpdateInfos = new Dictionary <TDependencyObject, StyleUpdateInfo>(); var newOrUpdatedStyleSheets = copy .Where(x => x.RenderTargetKind == RenderTargetKind.Stylesheet) .Select(x => x.StyleSheet) .Distinct() .ToHashSet(); var newOrUpdatedStyleHolders = copy .Where(x => x.ChangeKind == ChangeKind.New || x.ChangeKind == ChangeKind.Update || x.ChangeKind == ChangeKind.Remove) .Select(x => new { x.ChangeKind, x.StartFrom, x.StyleSheet, x.StyleSheetHolder }) .Distinct() .ToHashSet(); foreach (var item in newOrUpdatedStyleHolders) { var start = item.StartFrom ?? item.StyleSheetHolder; var domElement = treeNodeProvider.GetDomElement(start); if (!domElement.IsInLogicalTree) { continue; } EnsureParents(domElement, treeNodeProvider, dependencyPropertyService, nativeStyleService, styleUpdateInfos, SelectorType.LogicalTree); var discardOldMatchingStyles = newOrUpdatedStyleSheets.Contains(item.StyleSheet); SetupStyleInfo(domElement, item.StyleSheet, styleUpdateInfos, treeNodeProvider, dependencyPropertyService, nativeStyleService, discardOldMatchingStyles, item.ChangeKind == ChangeKind.Remove, SelectorType.LogicalTree); } foreach (var item in newOrUpdatedStyleHolders) { var start = item.StartFrom ?? item.StyleSheetHolder; var domElement = treeNodeProvider.GetDomElement(start); if (!domElement.IsInVisualTree) { continue; } EnsureParents(domElement, treeNodeProvider, dependencyPropertyService, nativeStyleService, styleUpdateInfos, SelectorType.VisualTree); var discardOldMatchingStyles = newOrUpdatedStyleSheets.Contains(item.StyleSheet); SetupStyleInfo(domElement, item.StyleSheet, styleUpdateInfos, treeNodeProvider, dependencyPropertyService, nativeStyleService, discardOldMatchingStyles, item.ChangeKind == ChangeKind.Remove, SelectorType.VisualTree); } var tasks = new List <Task <IList <IDomElement <TDependencyObject, TDependencyProperty> > > >(); var distinctCopy = copy.Select(x => new { x.StartFrom, x.StyleSheetHolder, x.StyleSheet }).Distinct().ToList(); foreach (var item in distinctCopy) { var start = item.StartFrom ?? item.StyleSheetHolder; if (!styleUpdateInfos.ContainsKey(start)) { continue; } //treeNodeProvider.Switch(SelectorType.VisualTree); var domElement = treeNodeProvider.GetDomElement(start); //visual.StyleInfo = styleUpdateInfos[start]; //if (!switchableTreeNodeProvider.IsInTree(start)) //{ // visual = null; //} //var task = Task.Run(() => UpdateMatchingStyles(item.StyleSheet, domElement, styleUpdateInfos, dependencyPropertyService, nativeStyleService)); //tasks.Add(task); tasks.Add(Task.FromResult(UpdateMatchingStyles(item.StyleSheet, domElement, styleUpdateInfos, dependencyPropertyService, nativeStyleService))); } //Task.WaitAll(tasks.ToArray()); var allFound = tasks.SelectMany(x => x.Result).ToList(); var allFoundElements = allFound.Select(x => x.Element).ToHashSet(); var allNotFoundKeys = styleUpdateInfos .Where(x => !allFoundElements.Contains(x.Key)) .ToList(); foreach (var item in allNotFoundKeys) { var styleUpdateInfo = item.Value; // styleUpdateInfo.CurrentMatchedSelectors = new List<string>(); styleUpdateInfo.OldMatchedSelectors = new LinkedHashSet <ISelector>(); styleUpdateInfo.DoMatchCheck = SelectorType.None; // remove style nativeStyleService.SetStyle(item.Key, dependencyPropertyService.GetInitialStyle(item.Key)); } var groups = styleUpdateInfos.Where(x => allFoundElements.Contains(x.Key)).GroupBy(x => x.Value.CurrentStyleSheet).ToList(); foreach (var group in groups) { GenerateStyles( group.Key, group.ToDictionary(x => x.Key, x => x.Value), applicationResourcesService, dependencyPropertyService, nativeStyleService, cssTypeHelper); } foreach (var f in allFound) { ApplyMatchingStylesNode(f, applicationResourcesService, nativeStyleService); } } finally { applicationResourcesService.EndUpdate(); } }
private static void GenerateStyles(StyleSheet styleSheet, IDictionary <TDependencyObject, StyleUpdateInfo> styleMatchInfos, IStyleResourcesService applicationResourcesService, IDependencyPropertyService <TDependencyObject, TStyle, TDependencyProperty> dependencyPropertyService, INativeStyleService <TStyle, TDependencyObject, TDependencyProperty> nativeStyleService, CssTypeHelper <TDependencyObject, TDependencyProperty, TStyle> cssTypeHelper) { applicationResourcesService.EnsureResources(); foreach (var styleMatchInfoKeyValue in styleMatchInfos) { var styleMatchInfo = styleMatchInfoKeyValue.Value; var matchedElementType = styleMatchInfo.MatchedType; foreach (var resourceKey in styleMatchInfo.CurrentMatchedSelectors) { if (applicationResourcesService.Contains(resourceKey)) { continue; } var s = resourceKey.Split('{')[1]; var rule = styleMatchInfo.CurrentStyleSheet.Rules.Where(x => x.SelectorString == s).First(); // // Debug.WriteLine("Generate Style " + resourceKey); CreateStyleDictionaryFromDeclarationBlockResult <TDependencyProperty> result = null; try { result = "CreateStyleDictionaryFromDeclarationBlock".Measure(() => CreateStyleDictionaryFromDeclarationBlock( styleSheet.Namespaces, rule.DeclarationBlock, matchedElementType, (TDependencyObject)styleSheet.AttachedTo, cssTypeHelper)); var propertyStyleValues = result.PropertyStyleValues; foreach (var error in result.Errors) { Debug.WriteLine($@" ERROR (normal) in Selector ""{rule.SelectorString}"": {error}"); styleSheet.AddError($@"ERROR in Selector ""{rule.SelectorString}"": {error}"); } var nativeTriggers = $"CreateTriggers ({rule.DeclarationBlock.Triggers.Count})".Measure(() => rule.DeclarationBlock.Triggers .Select(x => nativeStyleService.CreateTrigger(styleSheet, x, styleMatchInfo.MatchedType, (TDependencyObject)styleSheet.AttachedTo)) .ToList()); var initalStyle = dependencyPropertyService.GetInitialStyle(styleMatchInfoKeyValue.Key); if (initalStyle != null) { var subDict = nativeStyleService.GetStyleAsDictionary(initalStyle as TStyle); foreach (var i in subDict) { propertyStyleValues[i.Key] = i.Value; } var triggers = nativeStyleService.GetTriggersAsList(initalStyle as TStyle); nativeTriggers.AddRange(triggers); } foreach (var item in propertyStyleValues) { if (item.Value == null) { } } var style = "Create Style".Measure(() => nativeStyleService.CreateFrom(propertyStyleValues, nativeTriggers, matchedElementType)); applicationResourcesService.SetResource(resourceKey, style); // // Debug.WriteLine("Finished generate Style " + resourceKey); } catch (Exception e) { Debug.WriteLine($@" ERROR (exception) in Selector ""{rule.SelectorString}"": {e.Message}"); styleSheet.AddError($@"ERROR in Selector ""{rule.SelectorString}"": {e.Message}"); } } } }