From 9af480c2ee7ac338be6c2c01a2e371e075fbca10 Mon Sep 17 00:00:00 2001 From: Tobias Gummesson Date: Fri, 5 Jul 2013 12:27:23 -0700 Subject: [PATCH] Fixed so nodes in the property grid gets DesignItemProperty instances that really represents attached properties when an attached property is used. When setting a property value as attribute, fixed so namespace prefix is only used for attached properties, and if no prefix is defined for a non-default namespace a new unique prefix is generated. --- .../Project/PropertyGrid/PropertyGrid.cs | 6 +-- .../WpfDesign.XamlDom/Project/XamlProperty.cs | 51 +++++++++++------- .../WpfDesign/Project/ExtensionMethods.cs | 53 +++++++++++++++++-- .../Project/PropertyGrid/PropertyNode.cs | 21 +++++++- 4 files changed, 104 insertions(+), 27 deletions(-) diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/PropertyGrid/PropertyGrid.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/PropertyGrid/PropertyGrid.cs index 23248f7b26..426ac901e9 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/PropertyGrid/PropertyGrid.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/PropertyGrid/PropertyGrid.cs @@ -225,8 +225,8 @@ namespace ICSharpCode.WpfDesign.Designer.PropertyGrid } void AddNode(MemberDescriptor md) - { - var designProperties = SelectedItems.Select(item => item.Properties[md.Name]).ToArray(); + { + var designProperties = SelectedItems.Select(item => item.Properties.GetProperty(md)).ToArray(); if (!Metadata.IsBrowsable(designProperties[0])) return; PropertyNode node; @@ -252,7 +252,7 @@ namespace ICSharpCode.WpfDesign.Designer.PropertyGrid Category PickCategory(PropertyNode node) { if (Metadata.IsPopularProperty(node.FirstProperty)) return popularCategory; - if (node.FirstProperty.Name.Contains(".")) return attachedCategory; + if (node.FirstProperty.IsAttachedDependencyProperty()) return attachedCategory; var typeName = node.FirstProperty.DeclaringType.FullName; if (typeName.StartsWith("System.Windows.") || typeName.StartsWith("ICSharpCode.WpfDesign.Designer.Controls.")) return otherCategory; diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs index 3f5ce64d05..6e26a565cc 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs @@ -323,25 +323,38 @@ namespace ICSharpCode.WpfDesign.XamlDom // insert before specified index collection.InsertBefore(newChildNode, collectionElements[index].GetNodeForCollection()); } - } - - internal XmlAttribute SetAttribute(string value) - { - string ns = ParentObject.OwnerDocument.GetNamespaceFor(PropertyTargetType); - string name; - if (IsAttached) - name = PropertyTargetType.Name + "." + PropertyName; - else - name = PropertyName; - - var element = ParentObject.XmlElement; - if (string.IsNullOrEmpty(element.GetPrefixOfNamespace(ns))) { - element.SetAttribute(name, value); - return element.GetAttributeNode(name); - } else { - element.SetAttribute(name, ns, value); - return element.GetAttributeNode(name, ns); - } + } + + internal XmlAttribute SetAttribute(string value) + { + string name; + var element = ParentObject.XmlElement; + + if (IsAttached) + { + name = PropertyTargetType.Name + "." + PropertyName; + + string ns = ParentObject.OwnerDocument.GetNamespaceFor(PropertyTargetType); + string prefix = element.GetPrefixOfNamespace(ns); + + if (String.IsNullOrEmpty(prefix)) + { + prefix = ParentObject.OwnerDocument.GetPrefixForNamespace(ns); + } + + if (!string.IsNullOrEmpty(prefix)) + { + element.SetAttribute(name, ns, value); + return element.GetAttributeNode(name, ns); + } + } + else + { + name = PropertyName; + } + + element.SetAttribute(name, value); + return element.GetAttributeNode(name); } internal string GetNameForMarkupExtension() diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/ExtensionMethods.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/ExtensionMethods.cs index 69f9a54dfd..bd9df3670c 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/ExtensionMethods.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/ExtensionMethods.cs @@ -1,7 +1,8 @@ // Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) -// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) - -using System; +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.ComponentModel; using System.Windows; namespace ICSharpCode.WpfDesign @@ -22,6 +23,52 @@ namespace ICSharpCode.WpfDesign Math.Round(rect.Width, PlacementInformation.BoundsPrecision), Math.Round(rect.Height, PlacementInformation.BoundsPrecision) ); + } + + /// + /// Gets the design item property for the specified member descriptor. + /// + public static DesignItemProperty GetProperty(this DesignItemPropertyCollection properties, MemberDescriptor md) + { + DesignItemProperty prop = null; + + var pd = md as PropertyDescriptor; + if (pd != null) + { + var dpd = DependencyPropertyDescriptor.FromProperty(pd); + if (dpd != null) + { + if (dpd.IsAttached) + { + prop = properties.GetAttachedProperty(dpd.DependencyProperty); + } + else + { + prop = properties.GetProperty(dpd.DependencyProperty); + } + } + } + + if (prop == null) + { + prop = properties[md.Name]; + } + + return prop; + } + + /// + /// Gets if the specified design item property represents an attached dependency property. + /// + public static bool IsAttachedDependencyProperty(this DesignItemProperty property) + { + if (property.DependencyProperty != null) + { + var dpd = DependencyPropertyDescriptor.FromProperty(property.DependencyProperty, property.DesignItem.ComponentType); + return dpd.IsAttached; + } + + return false; } } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyGrid/PropertyNode.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyGrid/PropertyNode.cs index d212ead152..e3096a5907 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyGrid/PropertyNode.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyGrid/PropertyNode.cs @@ -34,7 +34,24 @@ namespace ICSharpCode.WpfDesign.PropertyGrid /// /// Gets the name of the property. /// - public string Name { get { return FirstProperty.Name; } } + public string Name + { + get + { + var dp = FirstProperty.DependencyProperty; + if (dp != null) + { + var dpd = DependencyPropertyDescriptor.FromProperty(dp, FirstProperty.DesignItem.ComponentType); + if (dpd.IsAttached) + { + // Will return the attached property name in the form of . + return dpd.Name; + } + } + + return FirstProperty.Name; + } + } /// /// Gets if this property node represents an event. @@ -366,7 +383,7 @@ namespace ICSharpCode.WpfDesign.PropertyGrid if (ValueItem != null) { var list = TypeHelper.GetAvailableProperties(ValueItem.Component) .OrderBy(d => d.Name) - .Select(d => new PropertyNode(new[] { ValueItem.Properties[d.Name] }, this)); + .Select(d => new PropertyNode(new[] { ValueItem.Properties.GetProperty(d) }, this)); foreach (var node in list) { if (Metadata.IsBrowsable(node.FirstProperty)) {