Unable to view Form in Designer

Dec 28, 2007 at 8:30 PM
I initially created a Windows Form application in the designer. After rebooting and reloading the project, the designer is unable to display the form. The Call Stack for the error is below:

at IronPython.CodeDom.RemoteReferences.GetType(String name)
at IronPython.CodeDom.LocalReferences.GetType(String name)
at IronPython.CodeDom.CodeWalker.GetTypeByName(String name)
at IronPython.CodeDom.CodeWalker.GetMemberType(CodeTypeReference parent, String name)
at IronPython.CodeDom.CodeWalker.Walk(FieldExpression node)
at IronPython.Compiler.Ast.FieldExpression.Walk(IAstWalker walker)
at IronPython.CodeDom.CodeWalker.Walk(CallExpression node)
at IronPython.Compiler.Ast.CallExpression.Walk(IAstWalker walker)
at IronPython.CodeDom.CodeWalker.Walk(ExpressionStatement node)
at IronPython.Compiler.Ast.ExpressionStatement.Walk(IAstWalker walker)
at IronPython.CodeDom.CodeWalker.Walk(SuiteStatement node)
at IronPython.Compiler.Ast.SuiteStatement.Walk(IAstWalker walker)
at IronPython.CodeDom.CodeWalker.ProcessBody(FunctionDefinition node, CodeMemberMethod method)
at IronPython.CodeDom.CodeWalker.Walk(FunctionDefinition node)
at IronPython.Compiler.Ast.FunctionDefinition.Walk(IAstWalker walker)
at IronPython.CodeDom.CodeWalker.ProcessSuite(ClassDefinition node, CodeTypeDeclaration ctd)
at IronPython.CodeDom.CodeWalker.Walk(ClassDefinition node)
at IronPython.Compiler.Ast.ClassDefinition.Walk(IAstWalker walker)
at IronPython.CodeDom.CodeWalker.ProcessSuite(ClassDefinition node, CodeTypeDeclaration ctd)
at IronPython.CodeDom.CodeWalker.Walk(ClassDefinition node)
at IronPython.Compiler.Ast.ClassDefinition.Walk(IAstWalker walker)
at IronPython.CodeDom.CodeWalker.Walk(SuiteStatement node)
at IronPython.Compiler.Ast.SuiteStatement.Walk(IAstWalker walker)
at IronPython.CodeDom.PythonParser.Parse(Parser p, String filename)
at IronPython.CodeDom.PythonParser.ParseMergeable(TextReader codeStream, IMergeDestination destination)
at IronPython.CodeDom.PythonParser.Parse(TextReader codeStream)
at System.CodeDom.Compiler.CodeDomProvider.Parse(TextReader codeStream)
at Microsoft.VisualStudio.Shell.Design.Serialization.CodeDom.CodeDomDocDataAdapter.get_CompileUnit()
at Microsoft.VisualStudio.Design.Serialization.CodeDom.VSCodeDomDesignerLoader.PerformLoad(IDesignerSerializationManager serializationManager)
at Microsoft.VisualStudio.Design.Serialization.CodeDom.VSCodeDomDesignerLoader.DeferredLoadHandler.Microsoft.VisualStudio.TextManager.Interop.IVsTextBufferDataEvents.OnLoadCompleted(Int32 fReload)
Dec 29, 2007 at 3:24 PM
Did you edit anything (add class variables or put in new methods before _init_ or InitializeComponent)? If so, open a notepad or a text editor and paste your code there and back out those changes out of IronPython Studio. It seems to be sensitive to custom changes (as is the full Visual Studio at least with IronPython). That should fix the problem of viewing the form. Make all the visual form changes you need and then paste the custom code back in. You have to be careful also, as if you add items / methods to the forms visually and save it can delete custom methods at the bottom of your file. Hope this helps.
Dec 30, 2007 at 12:05 AM
So, what is the recommended way to add an instance variable? If I assign to self.varname in the _init_ method, IronPython complains as the variable is not defined in _slots_. If I define the variable in _slots_, the forms designer cannot show the contents of the form anymore. If will give a blank form.

-- Marcel
Mar 8, 2008 at 11:59 PM
It would seem to me that this is a very serious bug in IronPython Studio because it means that no GUI form can have any state or equivalently, retain any persistent references to any other part of the system. Since if one creates a Windows Application, the form is where all actions in the system originate, this bug means that IronPython Studio, at the moment, can only create the most simplistic and state-less applications.

That said, here's a work-around that I found, after much trial an error:

Think Model-View-Controller and that the view therefore delegates all actions to some back-end "model" object. In this architecture, the form can get away with only one or just a few persistent references to other object(s) (technically, these would be "adapters" to the model, not the model itself). In short, encapsulate all method/function calls back to the model into a single class. For starters, one can make a direct connection to the back-end model, though one should go through an adapter class to decouple the model from the view.

To make that one reference to the adapter to the model, you need to fake out the GUI builder. That is, you need to make the GUI builder think that you are adding another GUI component, not a separate instance variable (field). The GUI builder appears to parse the class descriptor string at the gop of the form's code, so you need to add your instance variable name there in there, copying the syntax of the other variables:

class Form1(System.Windows.Forms.Form):
"""type(model) == MyModel, type(splitContainer1) == System.Windows.Forms.SplitContainer, ...etc

The class you associate with your variable is actually unimportant, but you might was well put the correct one in.

Now you also have to add the variable to the _slots_ array:

_slots_ = ['_model', '_splitContainer1', ... etc

You can now initialize the field in the constructor as normal:

def _init_(self):
self._model = BallModel(self)
self.InitializeComponent()
etc...

self.model is now accessible by any code in the form. All processing of form events should now be directed through self.model.

Your GUI designer should still be functional, though still as brittle as ever unfortunately. Once you do the above, you never need to add another field to the the form (luckily, since it is such a pain) -- for additional functionality, just add another method to the adapter to your model (and thus also to the model itself, if necessary).


BTW, you can use a similar "fake out" technique to get IronPython Studio to allow you to use the GUI builder to design a custom component:
1. Add a new Windows Form to your project.
2. Change the superclass of the form to "System.Windows.Forms.UserControl"
3. If desired, remove the outer class that VS puts on automatically and re-indent the code to make it easier to reference by other classes.

Unfortunately, IPY Studio's GUI toolbox doesn't automatically add the new component onto its list of available components as normal VS does, so you will always have to code it in manually wherever you use it.

Apr 1, 2008 at 4:44 PM
Edited Apr 1, 2008 at 4:45 PM
Thank you for the solution sbwong. However, I made an error while implementing your suggestions and I think I may have stumbled onto a simpler solution.

1. I made a new class file called "State.py" and put nothing into it.
2. I put "import State" at the top of my Form1.py file
3. I added "State.i = 0" to my _init()_ function in Form1.py to initialize a new variable to "State"
4. I am now able to access and modify the variable in the event handlers for GUI components

The GUI editor appears to still be functioning fine.
Sep 18, 2010 at 7:51 PM

Thank you guys for posting these solutions. I was really struggling with this myself. I ended up going with credford's solution, which worked pretty slick.

I'd like to eventually get to where I don't rely on the designer at all but, I have to admit, it's really nice when you're first learning the objects and such.