Click here to Skip to main content
15,881,715 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm programming in SolidWorks API, but this doesn't matter. I'm using modeless windows form (and for my case I can't use modal form). How can I reach that when the form opens, the code wait to click on button on this form. Therefore, I want to code go forward when I click button on modeless form and don't before.

Let say that I have this code:

C#
using SolidWorks.Interop.sldworks;
using SolidWorks.Interop.swconst;
using System.Runtime.InteropServices;
using System;
using System.Diagnostics;



   namespace Example.csproj
   {
       public partial class SolidWorksMacro
       {
           public void Main()
           {
               Debug.Print("This is main ");

               Form1 frm = new Form1();
               frm.Show();

               //wait on click to Butoon1 on Form1

               Debug.Print("We are on the end of programe ");
           }

           /// <summary>
           ///  The SldWorks swApp variable is pre-assigned for you.
           /// </summary>
           public SldWorks swApp;
       }
   }




and this code for form:

C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Example.csproj
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // With this butoon I want to continue program but don't before and I can't use modal form
        }
    }
}



Now the form is closed as soon as it's opened because the code continoue and it is finished and becose of this the form is closed. I want to the code wait until I will click button. But I realy need modeless form.

I know that this is very basic question but I don't find useful answer. I think that I can resolve this problem with events but I don't know how. I rode a lot about events. Can you give me the concrete resolve for this above code.
Posted

Rais an event in the child form:
C#
public partial class Form1 : Form
{
    public event EventHandler OkayToProceedChanged;

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        // With this butoon I want to continue program but don't before and I can't use modal form
        EventHandler eh = OkayToProceedChanged;
        if(eh != null)
        {
            eh(this, new EventArgs());
        }
    }
}

And subscribe to that event in the main program:
C#
private bool _okayToProceed = false;

public void Main()
{
    Debug.Print("This is main ");
 
    Form1 frm = new Form1();
    frm.OkayToProceedChanged += new EventHandler(Form1_OkayToProceedChanged);
    frm.Show();

    while(!_okayToProceed)
    {
        System.Threading.Thread.Sleep(10);
    }

    //wait on click to Butoon1 on Form1
    Debug.Print("We are on the end of programe ");

    /// <summary>
    ///  The SldWorks swApp variable is pre-assigned for you.
    /// </summary>
    public SldWorks swApp;
}

private void Form1_OkayToProceedChanged(object sender, EventArgs e)
{
    _okayToProceed = true;
}
 
Share this answer
 
v2
Comments
Member 9598596 14-Nov-12 7:04am    
Thanks for your quick respond. But now is the same probleme. Apparently the code go forward without clickin button, because of this the modeless form is closed avtomaticaly because the program is finished.
lukeer 14-Nov-12 7:16am    
Of course the Main method will proceed (stupid me!).
I updated my solution to incorporate TheOtherCPian's flag-and-sleep-loop approach.
Member 9598596 14-Nov-12 7:28am    
Now the form is showed but I don't see button and I can't click because program something working and working... After a lot of time I get the message: No symbols are loaded for any call stack frame. The source code can not be displayed.
lukeer 14-Nov-12 10:41am    
You definitely need two separate Threads[^]. One may pause, the other has to run the windows message pump. Usually the main thread does that. It is then in an infinite loop, nearly. That loop finishes when the main window closes and the Main method is allowed to exit.

You would therefore have to run the Form1 in another than the main thread so you can pause it and wait for the window to close (Since modal window is prohibited).
While it ain't pretty, you might want to look in the direction of using a flag that is accessible by both main and your form.

C#
public class AppGlobals
{
  public static bool IsFormFinished = false;
}

C#
private void button1_Click(object sender, EventArgs e)
{
  AppGlobals.IsFormFinished = true; 
}

C#
public void Main()
{
  Debug.Print("This is main ");
 
  Form1 frm = new Form1();
  frm.Show();
 
  //wait on click to Butoon1 on Form1
  while(!AppGlobals.IsFormFinished)
  {
    System.Threading.Thread.Sleep(10);
  }

  Debug.Print("We are on the end of programe ");
}
 
Share this answer
 
v2
Comments
Member 9598596 14-Nov-12 8:03am    
Maybe can you implement your solution in my code. Because I'm beginer and when I want to implement this code I get several errors.
BotCar 14-Nov-12 8:17am    
I've made the code more copy/paste friendly. What specific errors are you getting?
Member 9598596 14-Nov-12 8:33am    
Where I need to paste this public class AppGlobals......
If I paste in SolidWorksMacro.cs I get error The name 'AppGlobals' does not exist in the current context.

But if I paste in both (in SolidWorksMacro.cs and in Form1.cs) then is the problem the same which is in the solution 1 by lukeer. The window is showed but button is not showed and computer something working.....And I can't do nothing.


I just want to select something in solidworks graphic are when the form is open becose of this can't use modal form. And then when the entities wil be selected I will click button to go code forward

I want
BotCar 14-Nov-12 8:52am    
Don't put AppGlobals it in two files. That means you create two classes, one being used by Form1 and one being used by SolidWorksMacro. Instead, try to create a different file for the new class:
1. Go to Solution Explorer in Visual Studio (you are using Visual Studio, right?).
2. Right-click on you project (probably the second item you'll see, the first one is the solution (which is basically a collection of projects)).
3. Select Add -> Class
4. You will probably be shown some sort of dialog box where you can specify the name of the class (may be different based on the version of Visual Studio you have). Give the class a suitable name and continue.
5. Once the class is added, you should see a file with some skeleton code for you, such as:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Example.csproj
{
class AppGlobals
{
}
}

6. Add the line "public static bool IsFormFinished = false;" between the inner braces.
Member 9598596 14-Nov-12 9:17am    
Now is the same probleme which I describe above. Form is showed but button no and I I don't have access to form because the computer something work.
One way to do this if it is acceptable for the main form to be disabled while the dialog is showing is to do just that, i.e. set Enabled = false. It's important that the main thread is not blocked, which precludes the use of Thread.Sleep, as you have found out.

A very simple demo of the idea:
C#
namespace FauxModalDialogTest {
  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
    }

    protected override void OnShown(EventArgs e) {
      ShowPopup();
      base.OnShown(e);
    }

    private void ShowPopup() {
      Form f = new Form();
      f.Text = "Popup";
      f.FormClosed += new FormClosedEventHandler(f_FormClosed);
      f.Show(this);
      this.Enabled = false;
    }

    private void f_FormClosed(object sender, FormClosedEventArgs e) {
      this.Enabled = true;
    }
  }
}

Alan.
 
Share this answer
 
Comments
Member 9598596 14-Nov-12 11:47am    
Plese can you writte code for my example. Unfortunatly I don't know what I need put where.
Alan N 14-Nov-12 13:15pm    
I'm not clear about what you want your program to do. My answer assumes that you have shown the main form and then you want to show another form as a modeless dialog. The user will be prevented from interacting with the main form until a button is clicked on the dialog. Is that what you want?
Hi,

I think you need to change the Main method into this:
C#
public void Main()
{
    Debug.Print("This is main ");

   Application.Run(new Form1()); // use Application.Run instead of Form.Show

    //wait on click to Butoon1 on Form1

    Debug.Print("We are on the end of programe ");
}

And in the button1_Click method:
C#
private void button1_Click(object sender, EventArgs e)
{
      this.Close(); // close the form
}


Hope this helps.
 
Share this answer
 
Comments
Member 9598596 14-Nov-12 11:44am    
But with this I get modal dialog

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900