diff --git a/src/AddIns/BackendBindings/Python/PyWalker/ResolveWalker.cs b/src/AddIns/BackendBindings/Python/PyWalker/ResolveWalker.cs
index 8658fba23f..37340ebdf8 100644
--- a/src/AddIns/BackendBindings/Python/PyWalker/ResolveWalker.cs
+++ b/src/AddIns/BackendBindings/Python/PyWalker/ResolveWalker.cs
@@ -46,6 +46,12 @@ namespace PyWalker
return base.Walk(node);
}
+ public override bool Walk(AugmentedAssignStatement node)
+ {
+ writer.WriteLine("AugmentedAssignStatement");
+ return base.Walk(node);
+ }
+
public override bool Walk(AssignmentStatement node)
{
writer.WriteLine("AssignmentStatement");
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/IComponentCreator.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/IComponentCreator.cs
index 05455d0c58..52d0619b5b 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/IComponentCreator.cs
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/IComponentCreator.cs
@@ -46,5 +46,10 @@ namespace ICSharpCode.PythonBinding
/// Gets the type given its name.
///
Type GetType(string typeName);
+
+ ///
+ /// Gets the property descriptor associated with the event.
+ ///
+ PropertyDescriptor GetEventProperty(EventDescriptor e);
}
}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerGenerator.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerGenerator.cs
index 4037b2e55b..efdf756d8b 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerGenerator.cs
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerGenerator.cs
@@ -121,9 +121,15 @@ namespace ICSharpCode.PythonBinding
// new line before it.
IDocument doc = viewContent.DesignerCodeFileDocument;
string eventHandler = CreateEventHandler(eventMethodName, body, "\t");
- string newContent = "\r\n" + eventHandler;
int line = doc.LineSegmentCollection.Count;
- int offset = doc.GetLineSegment(line - 1).Offset;
+ LineSegment lastLineSegment = doc.GetLineSegment(line - 1);
+ int offset = lastLineSegment.Offset + lastLineSegment.Length;
+
+ string newContent = "\r\n" + eventHandler;
+ if (lastLineSegment.Length > 0) {
+ // Add an extra new line between the last line and the event handler.
+ newContent = "\r\n" + newContent;
+ }
doc.Insert(offset, newContent);
// Set position so it points to the line
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerLoader.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerLoader.cs
index b6950e7ade..27c0b14bf7 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerLoader.cs
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerLoader.cs
@@ -9,6 +9,7 @@ using System;
using System.CodeDom;
using System.Collections;
using System.ComponentModel;
+using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.Security.Permissions;
@@ -78,6 +79,15 @@ namespace ICSharpCode.PythonBinding
return serializationManager.GetType(typeName);
}
+ ///
+ /// Gets the property descriptor associated with the event.
+ ///
+ public PropertyDescriptor GetEventProperty(EventDescriptor e)
+ {
+ IEventBindingService eventBindingService = GetService(typeof(IEventBindingService)) as IEventBindingService;
+ return eventBindingService.GetEventProperty(e);
+ }
+
///
/// Passes the designer host's root component to the generator so it can update the
/// source code with changes made at design time.
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonForm.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonForm.cs
index 42958210a0..7b2b9e7c1f 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonForm.cs
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonForm.cs
@@ -7,8 +7,10 @@
using System;
using System.Drawing;
+using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
+using System.ComponentModel.Design;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
@@ -26,17 +28,58 @@ namespace ICSharpCode.PythonBinding
StringBuilder codeBuilder;
string indentString = String.Empty;
int indent;
+ IEventBindingService eventBindingService;
+ Attribute[] notDesignOnlyFilter = new Attribute[] { DesignOnlyAttribute.No };
+
+ class PythonFormEventBindingService : EventBindingService
+ {
+ public PythonFormEventBindingService()
+ : base(new ServiceContainer())
+ {
+ }
+
+ protected override string CreateUniqueMethodName(IComponent component, EventDescriptor e)
+ {
+ return String.Empty;
+ }
+
+ protected override ICollection GetCompatibleMethods(EventDescriptor e)
+ {
+ return new ArrayList();
+ }
+
+ protected override bool ShowCode()
+ {
+ return false;
+ }
+
+ protected override bool ShowCode(int lineNumber)
+ {
+ return false;
+ }
+
+ protected override bool ShowCode(IComponent component, EventDescriptor e, string methodName)
+ {
+ return false;
+ }
+ }
public PythonForm()
: this("\t")
{
}
- public PythonForm(string indentString)
+ public PythonForm(string indentString)
+ : this(indentString, new PythonFormEventBindingService())
{
- this.indentString = indentString;
}
+ PythonForm(string indentString, IEventBindingService eventBindingService)
+ {
+ this.indentString = indentString;
+ this.eventBindingService = eventBindingService;
+ }
+
///
/// Generates python code for the InitializeComponent method based on the controls added to the form.
///
@@ -71,8 +114,7 @@ namespace ICSharpCode.PythonBinding
public PropertyDescriptorCollection GetSerializableProperties(object obj)
{
List properties = new List();
- Attribute[] filter = new Attribute[] { DesignOnlyAttribute.No };
- foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(obj, filter).Sort()) {
+ foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(obj, notDesignOnlyFilter).Sort()) {
if (property.SerializationVisibility == DesignerSerializationVisibility.Visible) {
if (property.ShouldSerializeValue(obj)) {
properties.Add(property);
@@ -138,6 +180,8 @@ namespace ICSharpCode.PythonBinding
AppendControl(childControl, true, true);
}
}
+
+ AppendEventHandlers(propertyOwnerName, control);
}
///
@@ -238,5 +282,33 @@ namespace ICSharpCode.PythonBinding
AppendChildControlLayoutMethodCalls(control.Controls, methods);
}
}
+
+ ///
+ /// Generates code that wires an event to an event handler.
+ ///
+ ///
+ /// Note that the EventDescriptorCollection.Sort method does not work if the
+ /// enumerator is called first. Sorting will only occur if an item is retrieved after calling
+ /// Sort or CopyTo is called. The PropertyDescriptorCollection class does not behave
+ /// in the same way.
+ void AppendEventHandlers(string propertyOwnerName, Control control)
+ {
+ EventDescriptorCollection events = TypeDescriptor.GetEvents(control, notDesignOnlyFilter).Sort();
+ if (events.Count > 0) {
+ EventDescriptor dummyEventDescriptor = events[0];
+ }
+ foreach (EventDescriptor eventDescriptor in events) {
+ AppendEventHandler(propertyOwnerName, control, eventDescriptor);
+ }
+ }
+
+ void AppendEventHandler(string propertyOwnerName, Control control, EventDescriptor eventDescriptor)
+ {
+ PropertyDescriptor propertyDescriptor = eventBindingService.GetEventProperty(eventDescriptor);
+ if (propertyDescriptor.ShouldSerializeValue(control)) {
+ string methodName = (string)propertyDescriptor.GetValue(control);
+ AppendIndentedLine(GetPropertyName(propertyOwnerName, eventDescriptor.Name) + " += self." + methodName);
+ }
+ }
}
}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonFormWalker.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonFormWalker.cs
index 37de4dd87b..f64b3fd732 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonFormWalker.cs
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonFormWalker.cs
@@ -145,6 +145,25 @@ namespace ICSharpCode.PythonBinding
return false;
}
+ ///
+ /// Walks a statement of the form:
+ ///
+ /// self.a += self.b
+ ///
+ public override bool Walk(AugmentedAssignStatement node)
+ {
+ MemberExpression eventExpression = node.Left as MemberExpression;
+ string eventName = eventExpression.Name.ToString();
+
+ MemberExpression eventHandlerExpression = node.Right as MemberExpression;
+ string eventHandlerName = eventHandlerExpression.Name.ToString();
+
+ EventDescriptor eventDescriptor = TypeDescriptor.GetEvents(form).Find(eventName, false);
+ PropertyDescriptor propertyDescriptor = componentCreator.GetEventProperty(eventDescriptor);
+ propertyDescriptor.SetValue(form, eventHandlerName);
+ return false;
+ }
+
///
/// Walks the binary expression which is the right hand side of an assignment statement.
///
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateEventHandlerFormTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateEventHandlerFormTestFixture.cs
new file mode 100644
index 0000000000..f5324a42be
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/GenerateEventHandlerFormTestFixture.cs
@@ -0,0 +1,78 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.ComponentModel.Design.Serialization;
+using System.Drawing;
+using System.Windows.Forms;
+using ICSharpCode.PythonBinding;
+using NUnit.Framework;
+using PythonBinding.Tests.Utils;
+
+namespace PythonBinding.Tests.Designer
+{
+ ///
+ /// Tests that an event is wired to its event handler after the user specifies an event handler
+ /// method in the property grid.
+ ///
+ [TestFixture]
+ public class GenerateEventHandlerFormTestFixture
+ {
+ string generatedPythonCode;
+
+ [TestFixtureSetUp]
+ public void SetUpFixture()
+ {
+ using (DesignSurface designSurface = new DesignSurface(typeof(Form))) {
+ IDesignerHost host = (IDesignerHost)designSurface.GetService(typeof(IDesignerHost));
+ IEventBindingService eventBindingService = new MockEventBindingService(host);
+ Form form = (Form)host.RootComponent;
+ form.ClientSize = new Size(200, 300);
+
+ PropertyDescriptorCollection descriptors = TypeDescriptor.GetProperties(form);
+ PropertyDescriptor namePropertyDescriptor = descriptors.Find("Name", false);
+ namePropertyDescriptor.SetValue(form, "MainForm");
+
+ // Simulate giving a name to the Load event handler in the property grid.
+ EventDescriptorCollection events = TypeDescriptor.GetEvents(form);
+ EventDescriptor loadEvent = events.Find("Load", false);
+ PropertyDescriptor loadEventProperty = eventBindingService.GetEventProperty(loadEvent);
+ loadEventProperty.SetValue(form, "MainFormLoad");
+
+ // Add a second event handler method to check that the events are sorted alphabetically
+ // before the InitializeComponent method is generated.
+ EventDescriptor closedEvent = events.Find("FormClosed", false);
+ PropertyDescriptor closedEventProperty = eventBindingService.GetEventProperty(closedEvent);
+ closedEventProperty.SetValue(form, "MainFormClosed");
+
+ PythonForm pythonForm = new PythonForm(" ");
+ generatedPythonCode = pythonForm.GenerateInitializeComponentMethod(form);
+ }
+ }
+
+ [Test]
+ public void GeneratedCode()
+ {
+ string expectedCode = "def InitializeComponent(self):\r\n" +
+ " self.SuspendLayout()\r\n" +
+ " # \r\n" +
+ " # MainForm\r\n" +
+ " # \r\n" +
+ " self.ClientSize = System.Drawing.Size(200, 300)\r\n" +
+ " self.Name = \"MainForm\"\r\n" +
+ " self.FormClosed += self.MainFormClosed\r\n" +
+ " self.Load += self.MainFormLoad\r\n" +
+ " self.ResumeLayout(False)\r\n" +
+ " self.PerformLayout()\r\n";
+
+ Assert.AreEqual(expectedCode, generatedPythonCode);
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/InsertSecondEventHandlerTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/InsertSecondEventHandlerTestFixture.cs
new file mode 100644
index 0000000000..c9d021cc62
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/InsertSecondEventHandlerTestFixture.cs
@@ -0,0 +1,71 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using ICSharpCode.PythonBinding;
+using ICSharpCode.FormsDesigner;
+using ICSharpCode.SharpDevelop.Dom;
+using NUnit.Framework;
+using PythonBinding.Tests.Utils;
+
+namespace PythonBinding.Tests.Designer
+{
+ ///
+ /// Tests the PythonDesignerGenerator adds an extra new line between the previous event handler
+ /// and the new one inserted.
+ ///
+ [TestFixture]
+ public class InsertSecondEventHandlerTestFixture
+ {
+ string file;
+ int position;
+ bool insertedEventHandler;
+ MockTextEditorViewContent mockViewContent;
+ DerivedFormDesignerViewContent viewContent;
+
+ [TestFixtureSetUp]
+ public void SetUpFixture()
+ {
+ DerivedPythonDesignerGenerator generator = new DerivedPythonDesignerGenerator();
+ mockViewContent = new MockTextEditorViewContent();
+ viewContent = new DerivedFormDesignerViewContent(mockViewContent, new MockOpenedFile(@"C:\Projects\Python\mainform.py"));
+ generator.Attach(viewContent);
+ viewContent.DesignerCodeFileContent = GetTextEditorCode();
+
+ MockEventDescriptor mockEventDescriptor = new MockEventDescriptor("Click");
+ generator.InsertComponentEvent(null, mockEventDescriptor, "button1_click", String.Empty, out file, out position);
+ insertedEventHandler = generator.InsertComponentEvent(null, mockEventDescriptor, "button2_click", String.Empty, out file, out position);
+ }
+
+ [Test]
+ public void ExpectedCodeAfterEventHandlerInserted()
+ {
+ string expectedCode = GetTextEditorCode();
+ string eventHandler = "\tdef button1_click(self, sender, e):\r\n" +
+ "\t\tpass\r\n" +
+ "\r\n" +
+ "\tdef button2_click(self, sender, e):\r\n" +
+ "\t\tpass";
+ expectedCode = expectedCode + "\r\n" + eventHandler;
+
+ Assert.AreEqual(expectedCode, viewContent.DesignerCodeFileContent);
+ }
+
+ string GetTextEditorCode()
+ {
+ return "from System.Windows.Forms import Form\r\n" +
+ "\r\n" +
+ "class MainForm(Form):\r\n" +
+ "\tdef __init__(self):\r\n" +
+ "\t\tself.InitializeComponents()\r\n" +
+ "\t\r\n" +
+ "\tdef InitializeComponents(self):\r\n" +
+ "\t\tself._button1 = System.Windows.Forms.Button()\r\n" +
+ "\t\tself.Controls.Add(self._button1)\r\n";
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadEventHandlerTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadEventHandlerTestFixture.cs
new file mode 100644
index 0000000000..2c6d991337
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadEventHandlerTestFixture.cs
@@ -0,0 +1,52 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.Drawing;
+using System.IO;
+using System.Windows.Forms;
+
+using ICSharpCode.PythonBinding;
+using NUnit.Framework;
+using PythonBinding.Tests.Utils;
+
+namespace PythonBinding.Tests.Designer
+{
+ [TestFixture]
+ public class LoadEventHandlerTestFixture : LoadFormTestFixtureBase
+ {
+ public override string PythonCode {
+ get {
+ return "class TestForm(System.Windows.Forms.Form):\r\n" +
+ " def InitializeComponent(self):\r\n" +
+ " self.SuspendLayout()\r\n" +
+ " # \r\n" +
+ " # TestForm\r\n" +
+ " # \r\n" +
+ " self.Name = \"TestForm\"\r\n" +
+ " self.Load += self.TestFormLoad\r\n" +
+ " self.ResumeLayout(False)\r\n";
+ }
+ }
+
+ public EventDescriptor GetLoadEventDescriptor()
+ {
+ return TypeDescriptor.GetEvents(Form).Find("Load", true);
+ }
+
+ [Test]
+ public void EventPropertyDescriptorValueSetToEventHandlerMethodName()
+ {
+ EventDescriptor loadEventDescriptor = GetLoadEventDescriptor();
+ PropertyDescriptor property = base.GetEventProperty(loadEventDescriptor);
+ Assert.AreEqual("TestFormLoad", property.GetValue(Form) as String);
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadFontTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadFontTestFixture.cs
index e8dbc53ed7..9fde3374f0 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadFontTestFixture.cs
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadFontTestFixture.cs
@@ -34,12 +34,6 @@ namespace PythonBinding.Tests.Designer
}
}
- [TestFixtureSetUp]
- public new void SetUpFixture()
- {
- base.SetUpFixture();
- }
-
[Test]
public void FormBackColor()
{
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadFormTestFixtureBase.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadFormTestFixtureBase.cs
index 3be597c6c6..052a86b167 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadFormTestFixtureBase.cs
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/LoadFormTestFixtureBase.cs
@@ -9,6 +9,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
+using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.Drawing;
using System.Reflection;
@@ -38,7 +39,7 @@ namespace PythonBinding.Tests.Designer
[TestFixtureSetUp]
public void SetUpFixture()
- {
+ {
PythonFormWalker walker = new PythonFormWalker(this);
form = walker.CreateForm(PythonCode);
}
@@ -60,7 +61,7 @@ namespace PythonBinding.Tests.Designer
{
CreatedComponent c = new CreatedComponent(componentClass.FullName, name);
createdComponents.Add(c);
-
+
object instance = componentClass.Assembly.CreateInstance(componentClass.FullName);
return (IComponent)instance;
}
@@ -102,6 +103,11 @@ namespace PythonBinding.Tests.Designer
return type;
}
+ public PropertyDescriptor GetEventProperty(EventDescriptor e)
+ {
+ return new MockPropertyDescriptor("abc", "TestFormLoad", true);
+ }
+
protected Form Form {
get { return form; }
}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/MissingInitializeComponentMethodTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/MissingInitializeComponentMethodTestFixture.cs
index 94247d51ce..8164904cd7 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/MissingInitializeComponentMethodTestFixture.cs
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/MissingInitializeComponentMethodTestFixture.cs
@@ -87,6 +87,11 @@ namespace PythonBinding.Tests.Designer
public Type GetType(string typeName)
{
throw new NotImplementedException();
- }
+ }
+
+ public PropertyDescriptor GetEventProperty(EventDescriptor e)
+ {
+ return null;
+ }
}
}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonDesignerLoaderTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonDesignerLoaderTestFixture.cs
index e10a085b84..c301bce54e 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonDesignerLoaderTestFixture.cs
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonDesignerLoaderTestFixture.cs
@@ -38,6 +38,7 @@ namespace PythonBinding.Tests.Designer
MockExtenderProviderService mockExtenderProviderService;
IComponent rootComponent;
Form designedForm;
+ MockEventBindingService mockEventBindingService;
[TestFixtureSetUp]
public void SetUpFixture()
@@ -55,6 +56,10 @@ namespace PythonBinding.Tests.Designer
mockExtenderProviderService = new MockExtenderProviderService();
mockDesignerLoaderHost.AddService(typeof(IExtenderProviderService), mockExtenderProviderService);
+
+ mockEventBindingService = new MockEventBindingService();
+ mockDesignerLoaderHost.AddService(typeof(IEventBindingService), mockEventBindingService);
+
System.Console.WriteLine("Before BeginLoad");
loader.BeginLoad(mockDesignerLoaderHost);
System.Console.WriteLine("After BeginLoad");
@@ -123,6 +128,15 @@ namespace PythonBinding.Tests.Designer
Assert.AreEqual(designedForm, generator.MergeChangesRootComponent);
}
+ [Test]
+ public void GetEventPropertyUsesEventBindingService()
+ {
+ IEventBindingService eventBindingService = (IEventBindingService)mockEventBindingService;
+ EventDescriptor e = TypeDescriptor.GetEvents(typeof(Form)).Find("Load", true);
+ PropertyDescriptor expectedProperty = eventBindingService.GetEventProperty(e);
+ Assert.AreEqual(expectedProperty, loader.GetEventProperty(e));
+ }
+
///
/// The code that the designer loader will parse.
///
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj b/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj
index 26f1110791..08a9debf50 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj
@@ -155,6 +155,7 @@
+
@@ -168,11 +169,13 @@
+
+
@@ -249,6 +252,7 @@
+
@@ -257,6 +261,7 @@
+
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/TODO.txt b/src/AddIns/BackendBindings/Python/PythonBinding/Test/TODO.txt
index b30ab5b9fd..b666df3ded 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/TODO.txt
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/TODO.txt
@@ -86,4 +86,10 @@ def main(args):
ParentControl has BorderStyle = FixedSingle when created.
ChildControl has ParentControl as base class.
BorderStyle set to None in designer for ChildControl. Code should then be generated for BorderStyle since this
- is not the default
\ No newline at end of file
+ is not the default
+
+ * Event Handler loading code:
+
+ Handle invalid event name.
+ Check that += operator used.
+ Support event handlers on other controls.
\ No newline at end of file
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockEventBindingService.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockEventBindingService.cs
new file mode 100644
index 0000000000..066e92cd09
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockEventBindingService.cs
@@ -0,0 +1,52 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+
+namespace PythonBinding.Tests.Utils
+{
+ public class MockEventBindingService : EventBindingService
+ {
+ public MockEventBindingService(IServiceProvider serviceProvider)
+ : base(serviceProvider)
+ {
+ }
+
+ public MockEventBindingService()
+ : this(new ServiceContainer())
+ {
+ }
+
+ protected override string CreateUniqueMethodName(IComponent component, EventDescriptor e)
+ {
+ return String.Empty;
+ }
+
+ protected override ICollection GetCompatibleMethods(EventDescriptor e)
+ {
+ return new ArrayList();
+ }
+
+ protected override bool ShowCode()
+ {
+ return false;
+ }
+
+ protected override bool ShowCode(int lineNumber)
+ {
+ return false;
+ }
+
+ protected override bool ShowCode(IComponent component, EventDescriptor e, string methodName)
+ {
+ return false;
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockPropertyDescriptor.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockPropertyDescriptor.cs
new file mode 100644
index 0000000000..e2264cbd65
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockPropertyDescriptor.cs
@@ -0,0 +1,62 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.ComponentModel;
+using System.Windows.Forms;
+
+namespace PythonBinding.Tests.Utils
+{
+ public class MockPropertyDescriptor : PropertyDescriptor
+ {
+ object propertyValue;
+ bool shouldSerializeValue;
+
+ public MockPropertyDescriptor(string name, object value, bool shouldSerializeValue)
+ : base(name, null)
+ {
+ this.propertyValue = value;
+ this.shouldSerializeValue = shouldSerializeValue;
+ }
+
+ public override Type ComponentType {
+ get { return typeof(Form); }
+ }
+
+ public override bool IsReadOnly {
+ get { return false; }
+ }
+
+ public override Type PropertyType {
+ get { return typeof(String); }
+ }
+
+ public override bool CanResetValue(object component)
+ {
+ return true;
+ }
+
+ public override object GetValue(object component)
+ {
+ return this.propertyValue;
+ }
+
+ public override void ResetValue(object component)
+ {
+ }
+
+ public override void SetValue(object component, object value)
+ {
+ this.propertyValue = value;
+ }
+
+ public override bool ShouldSerializeValue(object component)
+ {
+ return shouldSerializeValue;
+ }
+ }
+}