private void CheckReferences(XName element, string value, NamespaceScope local, Styles localStyles) { XName reference = null; if (value.StartsWith("{Binding") || value.StartsWith("{TemplateBinding")) { var binding = ParseBinding(value, local); reference = binding.Converter; if (binding.Source != null) { var sourceRef = ParseResourceReference(binding.Source, local); var style = localStyles.FindStyle(element, sourceRef); if (style == null && !Whitelisted(sourceRef)) { Program.WriteError("Resource {0} not found", sourceRef.ToString()); } } } else if (value.StartsWith('{')) { reference = ParseResourceReference(value, local); } if (reference != null) { var style = localStyles.FindStyle(element, reference); if (style == null && !Whitelisted(reference)) { Program.WriteError("Resource {0} not found", reference.ToString()); } } }
public XElement FindStyle(XName typename, XName key) { // Check more specific target type match first. if (typename != null) { if (key == Program.emptyName) { // then this type reference might imply some child type references, // for example a <DataGrid> implies we will be using styles defined // for <DataGridRow>, <DataGridCell>, etc. foreach (XName childType in GetWpfChildTypes(typename)) { FindStyle(childType, Program.emptyName); } } XElement e = FindTargetType(typename, key); if (e != null) { return(e); } } if (this.keys.ContainsKey(key)) { var si = this.keys[key]; si.RefCount++; return(si.Element); } if (Parent != null) { return(Parent.FindStyle(typename, key)); } return(null); }
private void WalkResources(string fileName, XElement root, NamespaceScope scope, Styles styles) { var local = new NamespaceScope(scope); AddNamespaces(root, local); string codeRef = null; foreach (var a in root.Attributes()) { if (a.Name.LocalName == "TargetType") { // should have already been found in FindStyles. } else if (a.Name.LocalName == "Key" && a.Name.Namespace == XamlNsUri) { // should have already been found in FindStyles. } else if (a.Name.LocalName == "DataType") { // todo: check type references } else if (a.Name.LocalName.Contains("CodeRef")) { codeRef = a.Value; } else if (a.Name.LocalName != "xmlns" && a.Name.Namespace != XmlNsUri) { CheckReferences(GetTargetTypeName(root, a), a.Value, local, styles); } } Styles localStyles = null; // see if this element contains local styles foreach (var e in root.Elements()) { // find any local styles. if (e.Name.LocalName.EndsWith(".Resources")) { if (localStyles == null) { localStyles = new Styles(fileName + "+" + e.Name, styles); styles = localStyles; } FindStyles(fileName, e, local, localStyles); } } if (!string.IsNullOrEmpty(codeRef)) { // ah then the named styles are referenced from code, so record that fact foreach (var part in codeRef.Split(',')) { if (string.IsNullOrWhiteSpace(part)) { continue; } XName reference = QualifyName(part.Trim(), local); var style = styles.FindStyle(null, reference); if (style == null) { // might have been a TargetTyped resource XName targetType = styles.FindTargetType(reference); if (targetType != null) { style = styles.FindStyle(targetType, reference); if (style == null) { // might be a unnamed key TargetType only match style = styles.FindStyle(targetType, emptyName); } } if (style == null) { Program.WriteError("CodeRef {0} not found", reference.ToString()); } } } } // record possible reference to a TargetType of the matching element name. styles.FindStyle(GetTargetTypeName(root, null), Program.emptyName); // Now we have the "usage" of styles, either something in a UserControl, or a ControlTemplate in a ResourceDictionary. foreach (var e in root.Elements()) { WalkResources(fileName, e, local, styles); } if (localStyles != null) { localStyles.ReportUnreferenced(); } }