xsharp.eu • Unable to open forms created based on customized winform classes using the form designer
Page 1 of 3

Unable to open forms created based on customized winform classes using the form designer

Posted: Mon Oct 28, 2024 5:07 am
by xinjie
Hi, Development Team

I encountered the following problem as I continued my testing. Since my knowledge of DotNet is extremely limited, the following account may be verbose.

First, I created a custom class in the class library project that inherits from System.Windows.Forms.Form because I want forms in WinForm applications to have the same behavior and presentation in some common areas.

Code: Select all

Using System
Using System.Collections.Generic
Using System.ComponentModel
Using System.Text
Using System.Windows.Forms

Begin Namespace myTest
    Public Class myForm Inherit System.Windows.Forms.Form
        Public Constructor()
            This.Text           = "myForm"
            This.Deactivate += myForm_Deactivate
            This.Activated   += myForm_Activated
            Return
        End Constructor

        Private Method myForm_Deactivate(sender As System.Object, e As System.EventArgs) As Void Strict
            MessageBox("Deactivate")
        End Method

        Private Method myForm_Activated(sender As System.Object, e As System.EventArgs) As Void Strict
            MessageBox("Activated")
        End Method
    End Class
End Namespace
I build the class library project to get a DLL file: myTest.dll

Then I added the Windows Forms Application project to the same solution,And, add myTest.ll to the project's references.

I changed the form generated when I created the project so that it inherits from the previous myForm class.

Code: Select all

Using System
Using System.Collections.Generic
Using System.ComponentModel
Using System.Data
Using System.Drawing

Using System.Text

//using System.Windows.Forms
Using myTest

Begin Namespace myWinFormApp.Forms
    
    Public Partial Class Form1 Inherit myForm
        
        Public Constructor() Strict
            Self:InitializeComponent()
            Return
        End Constructor
    End Class
End Namespace
The form designer went blank after I changed the code.

I closed the code editing window and form designer。

VS IDE gives a message box when I double click the prg file again to open the form: the service microsoft.visualstudio.shell.interop.iselectioncontainer already exists in the service container

I thought there was something wrong with my code or design approach, so I redid it using C#. However, I did not encounter any problems.

I'm guessing this is an X# bug, but I'm not sure.

I expect a definite answer.

P.S. if I remove the subscribe from the constructor and include “This.Size = Size(200, 200)” in the constructor, then VS IDE gives the same message when I try to open the form inherited from myForm.

Re: Unable to open forms created based on customized winform classes using the form designer

Posted: Mon Oct 28, 2024 3:44 pm
by Chris
Hi xinjie,

This should work, and a quick test I made here works, but there are a lot of factors, project options, difference in code etc that could make a difference in the very fragile forms designer, so can you please zip and post the test solution to have a look? We should be able to pinpoint exactly what is causing the problem (probably in the parser) and fix it.

Re: Unable to open forms created based on customized winform classes using the form designer

Posted: Tue Oct 29, 2024 2:16 am
by xinjie
Hi, Chris

Thanks! Attached is the source code.
test.zip
(1.41 MiB) Downloaded 58 times

Re: Unable to open forms created based on customized winform classes using the form designer

Posted: Tue Oct 29, 2024 9:28 am
by Chris
HI xinjie,

Thanks a lot for the sample, I see some problems indeed:

1. Of course the dialog message about ISelectionContainer is a bug, will open a ticket for it

2. There is a problem (typo) in the code in the constructor of MyForm:

this.Size = Size(200, 200)

this is incorrectly using () for instantiating a Size type. The fullname for this type is System.Drawing.Size, but there is no USING System.Drawing in the prg, so the compiler thinks you are trying to access a memvar array with the name "Size" (since you are using parentheses). The way the form designer is implemented it actually "runs" this code to show the form, which of course fails at runtime, this is why the form designer cannot open the form. To fix this you can change the code to

this.Size = System.Drawing.Size{200, 200}

or add a USING System.Drawing and then only fix the problem of using () instead of {}:

this.Size = Size{200, 200}

The compiler could had found that problem at compile time, but because support for memvars is enabled, it cannot know what "Size" represents, until the code actually runs. If memvar support was disabled, then it would tell you that there's no such function or variable named "Size". So, for new code (not already existing code ported from VFP), I would suggest to turn memvar support completely off in the project options. This will help the compiler generate more robust code and catch problems in the code at compile time.

3. Also this code confuses the compiler, thinking again you are using a memvar:

this.Deactivate += myForm_Deactivate

The compiler thinks again that "myForm_Deactivate" represents a memvar, although I think that in this case it is a bug in X# and the compiler should realize that it's referring to a method, will open a ticket for this as well.

In order to fix this, you can simply again turn off memvar support (project options, Language page, disable "Enable Memvar Support" and "Enable Undeclared Variables Support"), so the compiler will now know for sure that you are referring to a method. If you do want to still be able to use memvars in the code, you can use an alternative syntax for registering events:

this.Deactivate += EventHandler{SELF, @myForm_Deactivate()}
this.Activated += EventHandler{SELF, @myForm_Activated()}

this will also fix the problem, but it's only a temp solution, it will not be always necessary to use this.

4. I also see a problem in building the solution, first time after making a change in the library, the main project fails to compile. You need to build it again to compile without errors, will log also this problem.

Re: Unable to open forms created based on customized winform classes using the form designer

Posted: Tue Oct 29, 2024 10:57 am
by xinjie
Hi, Chris

Thanks again!

The option to enable the memvar switch is actually intended for use with fox2+. This is because the documentation states that “This option is also needed in the FoxPro dialect if you want to make local variables visible to the macro compiler with the -fox2 compilation option.”

My understanding of the documentation is that if fox2+ is used then memvar+ must also be used. Am I wrong?

Re: Unable to open forms created based on customized winform classes using the form designer

Posted: Tue Oct 29, 2024 11:09 am
by Chris
Hi xinjie,

Indeed, if you want to make locals visible to the macrocompiler, then you need to have memvar+ enabled. But no need for fox2+ for this, this is used for making it possible to access array elements with "()", I think that comment in the documentation is outdated (the documentation about -fox2 itself is correct though).

Is it important for you to access locals from the macro compiler? Can't use for example a GLOBAL instead? Or a static field of a class?

Re: Unable to open forms created based on customized winform classes using the form designer

Posted: Tue Oct 29, 2024 11:29 am
by xinjie
Hi, Chris

I think I might use the macrocompiler although I'm not using it right now.
In terms of VFP conventions, I would expect the macrocompiler to recognize locals variable.

Here is my personal opinion:
For global variables, I try to avoid using them, even in VFP. It reduces the readability and maintainability of the code.
In VFP, I often use custom properties instead of global variables. So for static field of a class, at least I am not averse to it.

Re: Unable to open forms created based on customized winform classes using the form designer

Posted: Tue Oct 29, 2024 11:30 am
by xinjie
Also, is it possible to update the document related content?

Re: Unable to open forms created based on customized winform classes using the form designer

Posted: Tue Oct 29, 2024 12:41 pm
by Chris
Hi xinjie,

Yes, will do that, there are several items that need to be updated in the help file, will look into it the following days.

Regarding memvars in general, I understand that this is how it works in VFP and we are trying to provide as much as (optional) compatibility with this as possible. The problem though is that in VFP everything is resolved at runtime, so by using the same practice in X# for new code, you are losing almost all compile time checks and warnings that the X# compiler can show and prevent problems in the code surfacing only at runtime instead at compile time.

Of course it is perfectly valid to use the same VFP approach in X#, but I would suggest to also try experimenting with the strongly typed approach, without memvars. I'm sure that at first you will not prefer writing code this way it, but after seeing all the help the compiler can provide, maybe you will like also this approach.

Re: Unable to open forms created based on customized winform classes using the form designer

Posted: Tue Oct 29, 2024 1:11 pm
by xinjie
Hi, Chris

Thank you very much for your advice. I think for me personally, using strong types should be easy to adapt to.
I need to change one of my very bad habits which I picked up in VFP. Namely, sometimes using undefined variables just to implement the code quickly.