diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonPropertyValueAssignment.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonPropertyValueAssignment.cs
index fd7030a475..c131423995 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonPropertyValueAssignment.cs
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonPropertyValueAssignment.cs
@@ -6,7 +6,10 @@
//
using System;
+using System.Collections;
using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.ComponentModel.Design.Serialization;
using System.Drawing;
using System.Globalization;
using System.Windows.Forms;
@@ -42,70 +45,13 @@ namespace ICSharpCode.PythonBinding
Type propertyType = propertyValue.GetType();
if (propertyType == typeof(String)) {
return GetQuotedString((string)propertyValue);
- } else if (propertyType == typeof(Size)) {
- Size size = (Size)propertyValue;
- return size.GetType().FullName + "(" + size.Width + ", " + size.Height + ")";
- } else if (propertyType == typeof(SizeF)) {
- SizeF size = (SizeF)propertyValue;
- return size.GetType().FullName + "(" + size.Width + ", " + size.Height + ")";
- } else if (propertyType == typeof(Cursor)) {
- return GetCursorAsString(propertyValue as Cursor);
- } else if (propertyType == typeof(Point)) {
- Point point = (Point)propertyValue;
- return point.GetType().FullName + "(" + point.X + ", " + point.Y + ")";
- } else if (propertyType == typeof(Padding)) {
- Padding padding = (Padding)propertyValue;
- return padding.GetType().FullName + "(" + padding.Left + ", " + padding.Top + ", " + padding.Right + ", " + padding.Bottom + ")";
- } else if (propertyType == typeof(Color)) {
- Color color = (Color)propertyValue;
- return GetColorAsString(color);
- } else if (propertyType == typeof(Font)) {
- Font font = (Font)propertyValue;
- return GetFontAsString(font);
} else if (propertyType == typeof(AnchorStyles)) {
AnchorStyles anchor = (AnchorStyles)propertyValue;
return GetAnchorStyleAsString(anchor);
- } else if (propertyType.IsEnum) {
- return propertyType.FullName.Replace('+', '.') + "." + propertyValue.ToString();
}
- return propertyValue.ToString();
+ return ConvertTypeToString(propertyValue);
}
-
- static string GetCursorAsString(Cursor cursor)
- {
- TypeConverter converter = TypeDescriptor.GetConverter(typeof(Cursor));
- string cursorName = converter.ConvertToString(null, CultureInfo.InvariantCulture, cursor);
- return typeof(Cursors).FullName + "." + cursorName;
- }
-
- static string GetColorAsString(Color color)
- {
- if (color.IsSystemColor) {
- return GetColorAsString(color, typeof(SystemColors));
- } else if (color.IsNamedColor) {
- return GetColorAsString(color, typeof(Color));
- }
-
- // Custom color.
- return color.GetType().FullName + ".FromArgb(" + color.R + ", " + color.G + ", " + color.B + ")";
- }
-
- static string GetColorAsString(Color color, Type type)
- {
- foreach (PropertyInfo property in type.GetProperties(BindingFlags.Public | BindingFlags.Static)) {
- Color standardColor = (Color)property.GetValue(null, null);
- if (color == standardColor) {
- return type.FullName + "." + standardColor.Name;
- }
- }
- return String.Empty;
- }
-
- static string GetFontAsString(Font font)
- {
- return String.Concat(font.GetType().FullName, "(\"", font.Name, "\", ", font.Size.ToString(CultureInfo.InvariantCulture), ", ", typeof(FontStyle).FullName, ".", font.Style, ", ", typeof(GraphicsUnit).FullName, ".", font.Unit, ", ", font.GdiCharSet, ")");
- }
-
+
static string GetAnchorStyleAsString(AnchorStyles anchorStyles)
{
if (anchorStyles == AnchorStyles.None) {
@@ -139,5 +85,49 @@ namespace ICSharpCode.PythonBinding
{
return "\"" + text.Replace(@"\", @"\\").Replace("\"", "\\\"") + "\"";
}
+
+ ///
+ /// Looks for an instance descriptor for the property value's type and then tries to convert
+ /// the object creation using this instance descriptor.
+ ///
+ static string ConvertTypeToString(object propertyValue)
+ {
+ TypeConverter converter = TypeDescriptor.GetConverter(propertyValue);
+ if (converter.CanConvertTo(typeof(InstanceDescriptor))) {
+ InstanceDescriptor instanceDescriptor = converter.ConvertTo(propertyValue, typeof(InstanceDescriptor)) as InstanceDescriptor;
+ if (instanceDescriptor != null) {
+ StringBuilder text = new StringBuilder();
+ MemberInfo memberInfo = instanceDescriptor.MemberInfo;
+ string fullName = memberInfo.DeclaringType.FullName.Replace('+', '.'); // Remove any + chars from enums.
+ text.Append(fullName);
+ if (memberInfo.MemberType != MemberTypes.Constructor) {
+ text.Append('.');
+ text.Append(memberInfo.Name);
+ }
+
+ // Append arguments.
+ AppendArguments(text, instanceDescriptor.Arguments);
+
+ return text.ToString();
+ }
+ }
+ return converter.ConvertToString(null, CultureInfo.InvariantCulture, propertyValue);
+ }
+
+ static void AppendArguments(StringBuilder text, ICollection args)
+ {
+ if (args.Count > 0) {
+ int i = 0;
+ text.Append('(');
+ foreach (object arg in args) {
+ if (i > 0) {
+ text.Append(", ");
+ }
+ text.Append(ToString(arg));
+ ++i;
+ }
+ text.Append(')');
+ }
+ }
}
}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/ConvertCustomClassUsingTypeConverterTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/ConvertCustomClassUsingTypeConverterTestFixture.cs
new file mode 100644
index 0000000000..c0c6ef6c15
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/ConvertCustomClassUsingTypeConverterTestFixture.cs
@@ -0,0 +1,76 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.ComponentModel.Design.Serialization;
+using System.Drawing;
+using System.Globalization;
+using System.Reflection;
+using System.Windows.Forms;
+using ICSharpCode.PythonBinding;
+using NUnit.Framework;
+
+namespace PythonBinding.Tests.Designer
+{
+ [TypeConverter(typeof(CustomClassTypeConverter))]
+ class CustomClass
+ {
+ public string Name { get; set; }
+ public string Category { get; set; }
+
+ public CustomClass()
+ {
+ }
+
+ public CustomClass(string name, string category)
+ {
+ this.Name = name;
+ this.Category = category;
+ }
+ }
+
+ class CustomClassTypeConverter : TypeConverter
+ {
+ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
+ {
+ if (destinationType == typeof(InstanceDescriptor)) {
+ CustomClass c = value as CustomClass;
+ if (c != null) {
+ ConstructorInfo info = typeof(CustomClass).GetConstructor(new Type[] {typeof(String), typeof(String)});
+ return new InstanceDescriptor(info, new object[] {c.Name, c.Category});
+ }
+ }
+ return base.ConvertTo(context, culture, value, destinationType);
+ }
+
+ public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
+ {
+ if (destinationType == typeof(InstanceDescriptor)) {
+ return true;
+ }
+ return base.CanConvertTo(context, destinationType);
+ }
+ }
+
+ ///
+ /// Converts a custom class that has a custom TypeConverter defined.
+ /// This type converter implements an InstanceDescriptor which is used to generate the
+ /// code to create an instance of the class.
+ ///
+ [TestFixture]
+ public class ConvertCustomClassUsingTypeConverterTestFixture
+ {
+ [Test]
+ public void ConvertCustomClass()
+ {
+ CustomClass customClass = new CustomClass("Test", "Category");
+ Assert.AreEqual("PythonBinding.Tests.Designer.CustomClass(\"Test\", \"Category\")", PythonPropertyValueAssignment.ToString(customClass));
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj b/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj
index 47201f322b..c14edf558b 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj
@@ -161,6 +161,7 @@
+