Browse Source

Allow setting simple properties via DesignItem.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2238 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 19 years ago
parent
commit
de3656269f
  1. 31
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlComponentService.cs
  2. 4
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlDesignContext.cs
  3. 8
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelProperty.cs
  4. 3
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/themes/generic.xaml
  5. 15
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/AssemblyInfo.cs
  6. 97
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/ModelTestHelper.cs
  7. 30
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/ModelTests.cs
  8. 66
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/WpfDesign.Designer.Tests.csproj
  9. 15
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/app.config
  10. 48
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlDocument.cs
  11. 14
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObject.cs
  12. 44
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs
  13. 84
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs
  14. 9
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlPropertyInfo.cs
  15. 63
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeFinder.cs
  16. 35
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Tests/SystemTypesLoadTest.cs
  17. 1
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Tests/WpfDesign.XamlDom.Tests.csproj
  18. 6
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.sln

31
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlComponentService.cs

@ -8,11 +8,29 @@ @@ -8,11 +8,29 @@
using System;
using System.Collections.Generic;
using ICSharpCode.WpfDesign.XamlDom;
using System.Windows.Markup;
namespace ICSharpCode.WpfDesign.Designer.Xaml
{
sealed class XamlComponentService : IComponentService
{
#region IdentityEqualityComparer
sealed class IdentityEqualityComparer : IEqualityComparer<object>
{
internal static readonly IdentityEqualityComparer Instance = new IdentityEqualityComparer();
int IEqualityComparer<object>.GetHashCode(object obj)
{
return obj.GetHashCode();
}
bool IEqualityComparer<object>.Equals(object x, object y)
{
return x == y;
}
}
#endregion
readonly XamlDesignContext _context;
public XamlComponentService(XamlDesignContext context)
@ -23,7 +41,7 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml @@ -23,7 +41,7 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
public event EventHandler<DesignItemEventArgs> ComponentRegistered;
public event EventHandler<DesignItemEventArgs> ComponentUnregistered;
Dictionary<object, XamlDesignItem> _sites = new Dictionary<object, XamlDesignItem>();
Dictionary<object, XamlDesignItem> _sites = new Dictionary<object, XamlDesignItem>(IdentityEqualityComparer.Instance);
public DesignItem GetDesignItem(object component)
{
@ -36,10 +54,15 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml @@ -36,10 +54,15 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
public DesignItem RegisterComponentForDesigner(object component)
{
if (component == null)
throw new ArgumentNullException("component");
if (component == null) {
component = new NullExtension();
} else if (component is Type) {
component = new TypeExtension((Type)component);
}
throw new NotImplementedException();
XamlDesignItem item = new XamlDesignItem(_context.Document.CreateObject(component), _context);
_sites.Add(component, item);
return item;
}
/// <summary>

4
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlDesignContext.cs

@ -22,6 +22,10 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml @@ -22,6 +22,10 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
readonly XamlDesignItem _rootItem;
internal readonly XamlComponentService _componentService;
internal XamlDocument Document {
get { return _doc; }
}
/// <summary>
/// Creates a new XamlDesignContext instance.
/// </summary>

8
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelProperty.cs

@ -67,14 +67,18 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml @@ -67,14 +67,18 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
{
XamlComponentService componentService = _designItem.ComponentService;
DesignItem designItem = componentService.GetDesignItem(value);
XamlDesignItem designItem = (XamlDesignItem)componentService.GetDesignItem(value);
if (designItem != null) {
if (designItem.Parent != null)
throw new DesignerException("Cannot set value to design item that already has a parent");
_property.PropertyValue = designItem.XamlObject;
} else {
designItem = componentService.RegisterComponentForDesigner(value);
XamlPropertyValue val = _property.ParentObject.OwnerDocument.CreatePropertyValue(value, _property);
designItem = componentService.RegisterXamlComponentRecursive(val as XamlObject);
_property.PropertyValue = val;
}
_property.ValueOnInstance = value;
}
public override void Reset()

3
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/themes/generic.xaml

@ -2,6 +2,9 @@ @@ -2,6 +2,9 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:src="clr-namespace:ICSharpCode.WpfDesign.Designer"
>
<!--
This file contains the default styles used by the Controls in ICSharpCode.WpfDesign.Designer.Controls
-->
<Style TargetType="{x:Type src:Controls.ResizeThumb}">
<Setter Property="Template">

15
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/AssemblyInfo.cs

@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// Information about this assembly is defined by the following
// attributes.
//
// change them to the information which is associated with the assembly
// you compile.
[assembly: AssemblyTitle("WpfDesign.Designer.Tests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

97
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/ModelTestHelper.cs

@ -0,0 +1,97 @@ @@ -0,0 +1,97 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Text;
using System.IO;
using System.Xml;
using System.Diagnostics;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using NUnit.Framework;
using ICSharpCode.WpfDesign.Designer.Xaml;
namespace ICSharpCode.WpfDesign.Designer.Tests
{
/// <summary>
/// Base class for model tests.
/// </summary>
public class ModelTestHelper
{
protected StringBuilder log;
protected XamlDesignContext CreateContext(string xaml)
{
log = new StringBuilder();
XamlDesignContext context = new XamlDesignContext(new XmlTextReader(new StringReader(xaml)));
context.Services.Component.ComponentRegistered += delegate(object sender, DesignItemEventArgs e) {
log.AppendLine("Register " + ItemIdentity(e.Item));
};
context.Services.Component.ComponentUnregistered += delegate(object sender, DesignItemEventArgs e) {
log.AppendLine("Unregister " + ItemIdentity(e.Item));
};
return context;
}
protected DesignItem CreateCanvasContext(string xaml)
{
XamlDesignContext context = CreateContext(@"<Canvas
xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"">
" + xaml + "</Canvas>");
Canvas canvas = (Canvas)context.RootItem.Component;
DesignItem canvasChild = context.Services.Component.GetDesignItem(canvas.Children[0]);
Assert.IsNotNull(canvasChild);
return canvasChild;
}
protected void AssertCanvasDesignerOutput(string expectedXaml, DesignContext context)
{
expectedXaml =
"<?xml version=\"1.0\" encoding=\"utf-16\"?>\n" +
("<Canvas xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" " +
"xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n" + expectedXaml.Trim())
.Replace("\r", "").Replace("\n", "\n ")
+ "\n</Canvas>";
StringWriter stringWriter = new StringWriter();
XmlTextWriter xmlWriter = new XmlTextWriter(stringWriter);
xmlWriter.Formatting = Formatting.Indented;
context.Save(xmlWriter);
string actualXaml = stringWriter.ToString().Replace("\r", "");;
if (expectedXaml != actualXaml) {
Debug.WriteLine("expected xaml:");
Debug.WriteLine(expectedXaml);
Debug.WriteLine("actual xaml:");
Debug.WriteLine(actualXaml);
}
Assert.AreEqual(expectedXaml, actualXaml);
}
static string ItemIdentity(DesignItem item)
{
return item.Component.GetType().Name + " (" + item.GetHashCode() + ")";
}
protected void AssertLog(string expectedLog)
{
expectedLog = expectedLog.Replace("\r", "");
string actualLog = log.ToString().Replace("\r", "");
if (expectedLog != actualLog) {
Debug.WriteLine("expected log:");
Debug.WriteLine(expectedLog);
Debug.WriteLine("actual log:");
Debug.WriteLine(actualLog);
}
Assert.AreEqual(expectedLog, actualLog);
}
}
}

30
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/ModelTests.cs

@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Text;
using System.IO;
using System.Xml;
using System.Diagnostics;
using NUnit.Framework;
using ICSharpCode.WpfDesign.Designer.Xaml;
namespace ICSharpCode.WpfDesign.Designer.Tests
{
[TestFixture]
public class ModelTests : ModelTestHelper
{
[Test]
public void SetButtonWidth()
{
DesignItem button = CreateCanvasContext("<Button/>");
button.Properties["Width"].SetValue(100.0);
AssertCanvasDesignerOutput(@"<Button Width=""100"" />", button.Context);
AssertLog("");
}
}
}

66
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/WpfDesign.Designer.Tests.csproj

@ -0,0 +1,66 @@ @@ -0,0 +1,66 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{943DBBB3-E84E-4CF4-917C-C05AFA8743C1}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<OutputType>Library</OutputType>
<RootNamespace>ICSharpCode.WpfDesign.Designer.Tests</RootNamespace>
<AssemblyName>ICSharpCode.WpfDesign.Designer.Tests</AssemblyName>
<OutputPath>..\..\..\..\..\..\bin\UnitTests\</OutputPath>
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
<NoStdLib>False</NoStdLib>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>Full</DebugType>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<Optimize>False</Optimize>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DebugSymbols>False</DebugSymbols>
<DebugType>None</DebugType>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>TRACE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
<RegisterForComInterop>False</RegisterForComInterop>
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
<BaseAddress>4194304</BaseAddress>
<PlatformTarget>AnyCPU</PlatformTarget>
<FileAlignment>4096</FileAlignment>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
<ItemGroup>
<Reference Include="nunit.framework">
<HintPath>..\..\..\..\..\Tools\NUnit\nunit.framework.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\..\..\..\Main\GlobalAssemblyInfo.cs">
<Link>GlobalAssemblyInfo.cs</Link>
</Compile>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="ModelTestHelper.cs" />
<Compile Include="ModelTests.cs" />
<None Include="app.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\WpfDesign\Project\WpfDesign.csproj">
<Project>{66A378A1-E9F4-4AD5-8946-D0EC06C2902F}</Project>
<Name>WpfDesign</Name>
</ProjectReference>
<ProjectReference Include="..\Project\WpfDesign.Designer.csproj">
<Project>{78CC29AC-CC79-4355-B1F2-97936DF198AC}</Project>
<Name>WpfDesign.Designer</Name>
</ProjectReference>
</ItemGroup>
</Project>

15
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/app.config

@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="NUnit">
<section name="TestRunner"
type="System.Configuration.NameValueSectionHandler" />
</sectionGroup>
</configSections>
<NUnit>
<TestRunner>
<!-- Valid values are STA,MTA. Others ignored. -->
<add key="ApartmentState" value="STA" />
</TestRunner>
</NUnit>
</configuration>

48
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlDocument.cs

@ -7,6 +7,7 @@ @@ -7,6 +7,7 @@
using System;
using System.Xml;
using System.ComponentModel;
namespace ICSharpCode.WpfDesign.XamlDom
{
@ -18,6 +19,12 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -18,6 +19,12 @@ namespace ICSharpCode.WpfDesign.XamlDom
XmlDocument _xmlDoc;
XamlObject _rootElement;
XamlTypeFinder _typeFinder;
internal XmlDocument XmlDocument {
get { return _xmlDoc; }
}
/// <summary>
/// Gets the root xaml object.
/// </summary>
@ -45,9 +52,10 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -45,9 +52,10 @@ namespace ICSharpCode.WpfDesign.XamlDom
/// <summary>
/// Internal constructor, used by XamlParser.
/// </summary>
internal XamlDocument(XmlDocument xmlDoc)
internal XamlDocument(XmlDocument xmlDoc, XamlTypeFinder typeFinder)
{
this._xmlDoc = xmlDoc;
this._typeFinder = typeFinder;
}
/// <summary>
@ -57,5 +65,43 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -57,5 +65,43 @@ namespace ICSharpCode.WpfDesign.XamlDom
{
this._rootElement = rootElement;
}
/// <summary>
/// Create an XamlObject from the instance.
/// </summary>
public XamlObject CreateObject(object instance)
{
return (XamlObject)CreatePropertyValue(instance, null);
}
/// <summary>
/// Create a XamlPropertyValue for the specified value instance.
/// </summary>
public XamlPropertyValue CreatePropertyValue(object instance, XamlProperty forProperty)
{
if (instance == null)
throw new ArgumentNullException("instance");
Type elementType = instance.GetType();
TypeConverter c = TypeDescriptor.GetConverter(instance);
bool hasStringConverter = c.CanConvertTo(typeof(string)) && c.CanConvertFrom(typeof(string));
if (forProperty != null && hasStringConverter) {
return new XamlTextValue(c.ConvertToInvariantString(instance));
}
XmlElement xml = _xmlDoc.CreateElement(elementType.Name, GetNamespaceFor(elementType));
if (hasStringConverter) {
xml.InnerText = c.ConvertToInvariantString(instance);
}
return new XamlObject(this, xml, elementType, instance);
}
internal string GetNamespaceFor(Type type)
{
return _typeFinder.GetXmlNamespaceFor(type.Assembly, type.Namespace);
}
}
}

14
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObject.cs

@ -45,6 +45,15 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -45,6 +45,15 @@ namespace ICSharpCode.WpfDesign.XamlDom
}
#endregion
internal XmlElement XmlElement {
get { return element; }
}
internal override void AddNodeTo(XamlProperty property)
{
property.AddChildNodeToProperty(element);
}
/// <summary>
/// Gets the XamlDocument where this XamlObject is declared in.
/// </summary>
@ -76,6 +85,11 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -76,6 +85,11 @@ namespace ICSharpCode.WpfDesign.XamlDom
}
}
internal override void RemoveNodeFromParent()
{
element.ParentNode.RemoveChild(element);
}
/// <summary>
/// Finds the specified property, or creates it if it doesn't exist.
/// </summary>

44
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs

@ -92,7 +92,7 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -92,7 +92,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
throw new ArgumentNullException("document");
XamlParser p = new XamlParser();
p.settings = settings;
p.document = new XamlDocument(document);
p.document = new XamlDocument(document, settings.TypeFinder);
p.document.ParseComplete(p.ParseObject(document.DocumentElement));
return p.document;
}
@ -125,8 +125,41 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -125,8 +125,41 @@ namespace ICSharpCode.WpfDesign.XamlDom
XamlObject ParseObject(XmlElement element)
{
Type elementType = FindType(element.NamespaceURI, element.LocalName);
//object instance = Activator.CreateInstance(elementType);
object instance = settings.CreateInstanceCallback(elementType, emptyObjectArray);
XmlSpace oldXmlSpace = currentXmlSpace;
if (element.HasAttribute("xml:space")) {
currentXmlSpace = (XmlSpace)Enum.Parse(typeof(XmlSpace), element.GetAttribute("xml:space"), true);
}
XamlPropertyInfo defaultProperty = GetDefaultProperty(elementType);
XamlTextValue initializeFromTextValueInsteadOfConstructor = null;
if (defaultProperty == null) {
int numberOfTextNodes = 0;
bool onlyTextNodes = true;
foreach (XmlNode childNode in element.ChildNodes) {
if (childNode.NodeType == XmlNodeType.Text) {
numberOfTextNodes++;
} else if (childNode.NodeType == XmlNodeType.Element) {
onlyTextNodes = false;
}
}
if (onlyTextNodes && numberOfTextNodes == 1) {
foreach (XmlNode childNode in element.ChildNodes) {
if (childNode.NodeType == XmlNodeType.Text) {
initializeFromTextValueInsteadOfConstructor = (XamlTextValue)ParseValue(childNode);
}
}
}
}
object instance;
if (initializeFromTextValueInsteadOfConstructor != null) {
instance = TypeDescriptor.GetConverter(elementType).ConvertFromInvariantString(initializeFromTextValueInsteadOfConstructor.Text);
} else {
instance = settings.CreateInstanceCallback(elementType, emptyObjectArray);
}
XamlObject obj = new XamlObject(document, element, elementType, instance);
@ -135,12 +168,10 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -135,12 +168,10 @@ namespace ICSharpCode.WpfDesign.XamlDom
iSupportInitializeInstance.BeginInit();
}
XmlSpace oldXmlSpace = currentXmlSpace;
foreach (XmlAttribute attribute in element.Attributes) {
if (attribute.NamespaceURI == XamlConstants.XmlnsNamespace)
continue;
if (attribute.Name == "xml:space") {
currentXmlSpace = (XmlSpace)Enum.Parse(typeof(XmlSpace), attribute.Value, true);
continue;
}
if (GetAttributeNamespace(attribute) == XamlConstants.XamlNamespace)
@ -148,7 +179,6 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -148,7 +179,6 @@ namespace ICSharpCode.WpfDesign.XamlDom
ParseObjectAttribute(obj, attribute);
}
XamlPropertyInfo defaultProperty = GetDefaultProperty(elementType);
XamlPropertyValue setDefaultValueTo = null;
object defaultPropertyValue = null;
XamlProperty defaultCollectionProperty = null;
@ -171,6 +201,8 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -171,6 +201,8 @@ namespace ICSharpCode.WpfDesign.XamlDom
continue;
}
}
if (initializeFromTextValueInsteadOfConstructor != null)
continue;
XamlPropertyValue childValue = ParseValue(childNode);
if (childValue != null) {
if (defaultProperty != null && defaultProperty.IsCollection) {

84
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs

@ -22,6 +22,7 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -22,6 +22,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
XamlObject parentObject;
XamlPropertyInfo propertyInfo;
XamlPropertyValue propertyValue;
List<XamlPropertyValue> collectionElements;
bool _isCollection;
@ -65,11 +66,46 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -65,11 +66,46 @@ namespace ICSharpCode.WpfDesign.XamlDom
get { return propertyInfo.Name; }
}
/// <summary>
/// Gets the type the property is declared on.
/// </summary>
public Type PropertyTargetType {
get { return propertyInfo.TargetType; }
}
/// <summary>
/// Gets the value of the property. Can be null if the property is a collection property.
/// </summary>
public XamlPropertyValue PropertyValue {
get { return propertyValue; }
set {
if (IsCollection)
throw new InvalidOperationException();
Reset();
propertyValue = value;
propertyValue.AddNodeTo(this);
propertyValue.ParentProperty = this;
}
}
XmlElement _propertyElement;
internal void ParserSetPropertyElement(XmlElement propertyElement)
{
_propertyElement = propertyElement;
}
internal void AddChildNodeToProperty(XmlNode newChildNode)
{
if (_propertyElement == null) {
_propertyElement = parentObject.OwnerDocument.XmlDocument.CreateElement(
this.PropertyTargetType.Name + "." + this.PropertyName,
parentObject.OwnerDocument.GetNamespaceFor(this.PropertyTargetType)
);
parentObject.XmlElement.InsertBefore(_propertyElement, parentObject.XmlElement.FirstChild);
}
_propertyElement.AppendChild(newChildNode);
}
/// <summary>
@ -98,7 +134,15 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -98,7 +134,15 @@ namespace ICSharpCode.WpfDesign.XamlDom
/// </summary>
public void Reset()
{
throw new NotImplementedException();
if (propertyValue != null) {
propertyValue.RemoveNodeFromParent();
propertyValue.ParentProperty = null;
propertyValue = null;
}
if (_propertyElement != null) {
_propertyElement.ParentNode.RemoveChild(_propertyElement);
_propertyElement = null;
}
}
/// <summary>
@ -162,6 +206,10 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -162,6 +206,10 @@ namespace ICSharpCode.WpfDesign.XamlDom
get { return _parentProperty; }
internal set { _parentProperty = value; }
}
internal abstract void RemoveNodeFromParent();
internal abstract void AddNodeTo(XamlProperty property);
}
/// <summary>
@ -172,12 +220,18 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -172,12 +220,18 @@ namespace ICSharpCode.WpfDesign.XamlDom
XmlAttribute attribute;
XmlText textNode;
XmlSpace xmlSpace;
string textValue;
internal XamlTextValue(XmlAttribute attribute)
{
this.attribute = attribute;
}
internal XamlTextValue(string textValue)
{
this.textValue = textValue;
}
internal XamlTextValue(XmlText textNode, XmlSpace xmlSpace)
{
this.xmlSpace = xmlSpace;
@ -191,12 +245,19 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -191,12 +245,19 @@ namespace ICSharpCode.WpfDesign.XamlDom
get {
if (attribute != null)
return attribute.Value;
else if (textValue != null)
return textValue;
else
return NormalizeWhitespace(textNode.Value);
}
set {
if (value == null)
throw new ArgumentNullException("value");
if (attribute != null)
attribute.Value = value;
else if (textValue != null)
textValue = value;
else
textNode.Value = value;
}
@ -236,5 +297,26 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -236,5 +297,26 @@ namespace ICSharpCode.WpfDesign.XamlDom
return this.Text;
}
}
internal override void RemoveNodeFromParent()
{
if (attribute != null)
attribute.OwnerElement.RemoveAttribute(attribute.Name);
else if (textNode != null)
textNode.ParentNode.RemoveChild(textNode);
}
internal override void AddNodeTo(XamlProperty property)
{
if (attribute != null) {
property.ParentObject.XmlElement.Attributes.Append(attribute);
} else if (textValue != null) {
property.ParentObject.XmlElement.SetAttribute(property.PropertyName, textValue);
attribute = property.ParentObject.XmlElement.GetAttributeNode(property.PropertyName);
textValue = null;
} else {
property.AddChildNodeToProperty(textNode);
}
}
}
}

9
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlPropertyInfo.cs

@ -23,6 +23,7 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -23,6 +23,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
public abstract object GetValue(object instance);
public abstract void SetValue(object instance, object value);
public abstract TypeConverter TypeConverter { get; }
public abstract Type TargetType { get; }
public abstract string Name { get; }
public abstract string FullyQualifiedName { get; }
public abstract bool IsAttached { get; }
@ -55,6 +56,10 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -55,6 +56,10 @@ namespace ICSharpCode.WpfDesign.XamlDom
}
}
public override Type TargetType {
get { return _getMethod.DeclaringType; }
}
public override string Name {
get { return _name; }
}
@ -102,6 +107,10 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -102,6 +107,10 @@ namespace ICSharpCode.WpfDesign.XamlDom
_propertyDescriptor.SetValue(instance, value);
}
public override Type TargetType {
get { return _propertyDescriptor.ComponentType; }
}
public override TypeConverter TypeConverter {
get {
if (_propertyDescriptor.PropertyType == typeof(object))

63
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeFinder.cs

@ -18,7 +18,7 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -18,7 +18,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
/// </summary>
public class XamlTypeFinder : ICloneable
{
sealed class AssemblyNamespaceMapping
sealed class AssemblyNamespaceMapping : IEquatable<AssemblyNamespaceMapping>
{
internal readonly Assembly Assembly;
internal readonly string Namespace;
@ -28,15 +28,37 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -28,15 +28,37 @@ namespace ICSharpCode.WpfDesign.XamlDom
this.Assembly = assembly;
this.Namespace = @namespace;
}
public override int GetHashCode()
{
return Assembly.GetHashCode() ^ Namespace.GetHashCode();
}
public override bool Equals(object obj)
{
return Equals(obj as AssemblyNamespaceMapping);
}
public bool Equals(AssemblyNamespaceMapping other)
{
return other != null && other.Assembly == this.Assembly && other.Namespace == this.Namespace;
}
}
sealed class XamlNamespace
{
internal readonly string XmlNamespace;
internal XamlNamespace(string xmlNamespace)
{
this.XmlNamespace = xmlNamespace;
}
internal List<AssemblyNamespaceMapping> ClrNamespaces = new List<AssemblyNamespaceMapping>();
internal XamlNamespace Clone()
{
XamlNamespace copy = new XamlNamespace();
XamlNamespace copy = new XamlNamespace(this.XmlNamespace);
// AssemblyNamespaceMapping is immutable
copy.ClrNamespaces.AddRange(this.ClrNamespaces);
return copy;
@ -44,6 +66,7 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -44,6 +66,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
}
Dictionary<string, XamlNamespace> namespaces = new Dictionary<string, XamlNamespace>();
Dictionary<AssemblyNamespaceMapping, string> reverseDict = new Dictionary<AssemblyNamespaceMapping, string>();
/// <summary>
/// Gets a type referenced in XAML.
@ -76,8 +99,23 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -76,8 +99,23 @@ namespace ICSharpCode.WpfDesign.XamlDom
return null;
}
XamlNamespace ParseNamespace(string name)
/// <summary>
/// Gets the XML namespace that can be used for the specified assembly/namespace combination.
/// </summary>
public string GetXmlNamespaceFor(Assembly assembly, string @namespace)
{
AssemblyNamespaceMapping mapping = new AssemblyNamespaceMapping(assembly, @namespace);
string xmlNamespace;
if (reverseDict.TryGetValue(mapping, out xmlNamespace)) {
return xmlNamespace;
} else {
return "clr-namespace:" + mapping.Namespace + ";assembly=" + mapping.Assembly.GetName().Name;
}
}
XamlNamespace ParseNamespace(string xmlNamespace)
{
string name = xmlNamespace;
Debug.Assert(name.StartsWith("clr-namespace:"));
name = name.Substring("clr-namespace:".Length);
string namespaceName, assembly;
@ -93,14 +131,20 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -93,14 +131,20 @@ namespace ICSharpCode.WpfDesign.XamlDom
}
assembly = name.Substring("assembly=".Length);
}
XamlNamespace ns = new XamlNamespace();
XamlNamespace ns = new XamlNamespace(xmlNamespace);
Assembly asm = LoadAssembly(assembly);
if (asm != null) {
ns.ClrNamespaces.Add(new AssemblyNamespaceMapping(asm, namespaceName));
AddMappingToNamespace(ns, new AssemblyNamespaceMapping(asm, namespaceName));
}
return ns;
}
void AddMappingToNamespace(XamlNamespace ns, AssemblyNamespaceMapping mapping)
{
ns.ClrNamespaces.Add(mapping);
reverseDict[mapping] = ns.XmlNamespace;
}
/// <summary>
/// Registers XAML namespaces defined in the <paramref name="assembly"/> for lookup.
/// </summary>
@ -111,14 +155,14 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -111,14 +155,14 @@ namespace ICSharpCode.WpfDesign.XamlDom
foreach (XmlnsDefinitionAttribute xmlnsDef in assembly.GetCustomAttributes(typeof(XmlnsDefinitionAttribute), true)) {
XamlNamespace ns;
if (!namespaces.TryGetValue(xmlnsDef.XmlNamespace, out ns)) {
ns = namespaces[xmlnsDef.XmlNamespace] = new XamlNamespace();
ns = namespaces[xmlnsDef.XmlNamespace] = new XamlNamespace(xmlnsDef.XmlNamespace);
}
if (string.IsNullOrEmpty(xmlnsDef.AssemblyName)) {
ns.ClrNamespaces.Add(new AssemblyNamespaceMapping(assembly, xmlnsDef.ClrNamespace));
AddMappingToNamespace(ns, new AssemblyNamespaceMapping(assembly, xmlnsDef.ClrNamespace));
} else {
Assembly asm = LoadAssembly(xmlnsDef.AssemblyName);
if (asm != null) {
ns.ClrNamespaces.Add(new AssemblyNamespaceMapping(asm, xmlnsDef.ClrNamespace));
AddMappingToNamespace(ns, new AssemblyNamespaceMapping(asm, xmlnsDef.ClrNamespace));
}
}
}
@ -154,6 +198,9 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -154,6 +198,9 @@ namespace ICSharpCode.WpfDesign.XamlDom
foreach (KeyValuePair<string, XamlNamespace> pair in source.namespaces) {
this.namespaces.Add(pair.Key, pair.Value.Clone());
}
foreach (KeyValuePair<AssemblyNamespaceMapping, string> pair in source.reverseDict) {
this.reverseDict.Add(pair.Key, pair.Value);
}
}
object ICloneable.Clone()

35
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Tests/SystemTypesLoadTest.cs

@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using NUnit.Framework;
namespace ICSharpCode.WpfDesign.XamlDom.Tests
{
[TestFixture]
public class SystemTypesLoadTest : TestHelper
{
[Test]
public void Int32()
{
TestLoading(@"<Int32 xmlns=""clr-namespace:System;assembly=mscorlib"">3</Int32>");
}
[Test]
public void Double()
{
TestLoading(@"<Double xmlns=""clr-namespace:System;assembly=mscorlib"">3.1</Double>");
}
[Test]
public void String()
{
TestLoading(@"<String xmlns=""clr-namespace:System;assembly=mscorlib"">text</String>");
}
}
}

1
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Tests/WpfDesign.XamlDom.Tests.csproj

@ -60,6 +60,7 @@ @@ -60,6 +60,7 @@
<Compile Include="ExampleClassContainer.cs" />
<Compile Include="SamplesTests.cs" />
<Compile Include="SimpleLoadTests.cs" />
<Compile Include="SystemTypesLoadTest.cs" />
<Compile Include="TestHelper.cs" />
<Compile Include="WhitespaceTests.cs" />
<Compile Include="XamlTypeFinderTests.cs" />

6
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.sln

@ -12,6 +12,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StandaloneDesigner", "Stand @@ -12,6 +12,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StandaloneDesigner", "Stand
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign", "WpfDesign\Project\WpfDesign.csproj", "{66A378A1-E9F4-4AD5-8946-D0EC06C2902F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfDesign.Designer.Tests", "WpfDesign.Designer\Tests\WpfDesign.Designer.Tests.csproj", "{943DBBB3-E84E-4CF4-917C-C05AFA8743C1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -38,5 +40,9 @@ Global @@ -38,5 +40,9 @@ Global
{66A378A1-E9F4-4AD5-8946-D0EC06C2902F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{66A378A1-E9F4-4AD5-8946-D0EC06C2902F}.Release|Any CPU.Build.0 = Release|Any CPU
{66A378A1-E9F4-4AD5-8946-D0EC06C2902F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{943DBBB3-E84E-4CF4-917C-C05AFA8743C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{943DBBB3-E84E-4CF4-917C-C05AFA8743C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{943DBBB3-E84E-4CF4-917C-C05AFA8743C1}.Release|Any CPU.Build.0 = Release|Any CPU
{943DBBB3-E84E-4CF4-917C-C05AFA8743C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
EndGlobalSection
EndGlobal

Loading…
Cancel
Save