Solved

How to disable mouse click on MDI parent while process is taking place in MDI child

Posted on 2010-08-20
36
1,435 Views
Last Modified: 2012-08-13

I have two forms. Form1 as parent and Form2 as child in windows application. In form2 i have some process taking place on button click, While process is taking place in child form i dont want my parent form to be clicked [ i want to disable my mouse click on parent form ].


Help appreciated
 
0
Comment
Question by:RakeshBhandari
  • 10
  • 7
  • 6
  • +5
36 Comments
 
LVL 19

Expert Comment

by:daveamour
Comment Utility
Try MdiParent.Enabled = false;
0
 
LVL 25

Expert Comment

by:Luis Pérez
Comment Utility
Mmmmm... you can set Enabled property of MDI parent to False; but this has the disadvantage that, as child form is owned by MDI parent, not only you'll disable clicking on parent, but also on all child forms open. It it's OK to you, then try it.

this.MdiParent.Enabled = false;

When your process ends then

this.MdiParent.Enabled = true;

Hope that helps.
0
 
LVL 25

Expert Comment

by:Luis Pérez
Comment Utility
Sorry, posted later daveamour...
0
 
LVL 25

Expert Comment

by:Luis Pérez
Comment Utility
If solution is right to you give points to daveamour
0
 
LVL 9

Expert Comment

by:puru1981
Comment Utility
you can open child form using showdialog method. it will not allow to click on the parent form.
0
 
LVL 6

Expert Comment

by:mohd_haq
Comment Utility
Hi,
How about using ShowDialog to load the Child form as modal. This will disable the parent form until you close the child form.

eg:
form2 f2 = new form2();
f2.ShowDialog();

Hope this hepls you.
0
 
LVL 2

Author Comment

by:RakeshBhandari
Comment Utility
Hi
   This disabling the parent and child form. But when click  childform and  parent form,  cursormode change to cursorwait and function of the my progress bar stoped  why?
 
0
 
LVL 25

Expert Comment

by:Luis Pérez
Comment Utility
This must not happen. Maybe the progress bar stopped as the form is disabled, but the code function is still executing.

If not, you can always throw your background process into a new thread and after all disable the MDI parent. When threads ends then you can re-enable your MDI parent.
0
 
LVL 2

Author Comment

by:RakeshBhandari
Comment Utility
Yes. the  code is executing. But how stop cursormode change ?
0
 
LVL 25

Expert Comment

by:Luis Pérez
Comment Utility
Try
this.UseWaitCursor = false;
or
this.Cursor = Cursors.Pointer;

0
 
LVL 16

Expert Comment

by:kris_per
Comment Utility
Disabling the mdi form (or disabling mouse-click by any way) will disable your whole application; you cant even click on the titlebar or move the window or anything...

May be disabling specific controls or items (like menu/item, toolbar/item) in the mdi form can be considered...

But it would be even better if you put your processing code in a modal form/with progress/cancel button...for e.g. child form can have a button 'Process'. when user clicks, show another form using ShowDialog..this form will have progress bar with cancel button...and user cant click anywhere outside this form...

0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
The WaitCursor is not appearing because you disabled the form but because the main UI thread is busy processing the code.  As RolandDeschain stated earlier, you need to move that code to another thread.  The BackgroundWorker() control makes this really easy:
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

kris_per gave some great advice on disabling only specific controls as well to "simulate" a disabled main form.  Otherwise it will just be a static "dead" form that the user will probably think has crashed.  You can use the RunWorkerCompleted() event of the BackgroundWorker() control to turn everything back on.
0
 
LVL 9

Expert Comment

by:puru1981
Comment Utility
can you elaborate more on the issue? which technique you have applied and what are you doing on opening a child form.?
0
 
LVL 16

Expert Comment

by:Vikram Singh Saini
Comment Utility
Hello Rakesh,

But when click  childform and  parent form,  cursormode change to  cursorwait and function of the my progress bar stoped

You can use your the function of your progress bar in separate thread or you can use BackgroundWorker component.

Regards,
VSS
0
 
LVL 6

Expert Comment

by:mohd_haq
Comment Utility
Hi,

what you can do here is open the child form as modal window(using form2.ShowDialog();). this will disable the parent window and then disable the child window by setting its enabled value to false. consider the following code

private void button1_Click(object sender, EventArgs e)
        {

            this.Enabled = false;

            // do something
            Thread.Sleep(3000);
            //end
       
            this.Enabled = true;
        }

here i am stop the thread execution for three seconds just to show what it does. you can add the code you want to execute instead of that and see if  thats what you want. Hope this helps you.

0
 
LVL 2

Author Comment

by:RakeshBhandari
Comment Utility
Thread.Sleep(3000);

suppose if i want to add thread which namespace i have to use ?
0
 
LVL 16

Expert Comment

by:Vikram Singh Saini
Comment Utility
Hi,

To use Thread you have to use System.Threading namespace.

Regards,
VSS
0
 
LVL 2

Author Comment

by:RakeshBhandari
Comment Utility
Hi,
    I used above metioned code as per that my code is

                            UpLoad up = new UpLoad();(this is my childform)
                             up.ShowDialog();
                             this.Enabled = false;

                             // Some code
                           Thread.Sleep(3000);
               
                           this.Enabled = true;

when  i click on button its creating duplicate  window of childform with blank textbox. there is no furher process.
when close newly created  child window process is happening with above said defects

 
0
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
LVL 9

Expert Comment

by:puru1981
Comment Utility
just remove this code

 this.Enabled = false;

                             // Some code
                           Thread.Sleep(3000);
               
                           this.Enabled = true;

because you are doing it by code so it will enable the parent form. after removing this code you will be not able to click on parent form.
0
 
LVL 6

Expert Comment

by:mohd_haq
Comment Utility
Hi,
I think you messed up with your code. First of all Thread.Sleep(3000); has nothing to do with your code. I just included it to show how the code works. ok then lets start form your mdi parent window
you invoke the child form from the parent form as  
                            UpLoad up = new UpLoad();(this is my childform)
                             up.ShowDialog();
thats correct. But you shouldn't enable/disable the parent form here. you should add the following in your child forms button click event or any event where you want to perform something and want the parent and child form to be disabled:

private void button1_Click(object sender, EventArgs e) // or any other control event
        {

            this.Enabled = false;

            // do something
            // add the code in the child form that you need to perform
            // and make child and parent form disabled.
            //end
       
            this.Enabled = true;
        }
Do ask if you still have doubts. Hope this helps you.
0
 
LVL 16

Expert Comment

by:Vikram Singh Saini
Comment Utility
Hi,

I have tried to create an application trying to achieve your objective.

There are two forms. Form1 has menu bar to open ChildForm and button1 to show messagebox simply. Second Form Form2 is childform and is having one button & richTextBox. On clicking button loop executes and write values in richtextbox.

While the processing goes on the mouse click gets disable in Form1 but as processing finishes mouse click gets enable.

 Please check the code and let me know back.

Regards,
VSS

--------------------------
//Form1.cs (MDI Container)
--------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace ee_TestCode
{
    public partial class Form1 : Form, IMessageFilter
    {
        private const int LButtonDown = 0x201;
        private const int LButtonUp = 0x202;
        private const int LButtonDoubleClick = 0x203;

        public Form1()
        {
            InitializeComponent();
        }

        public bool PreFilterMessage(ref System.Windows.Forms.Message m)
        {
            if (m.Msg == 0x201 || m.Msg == 0x202 || m.Msg == 0x203)
                return true;
            else
                return false;
        }

        public void DisableMouseClicks()
        {
            Application.AddMessageFilter(this);
        }

        public void EnableMouseClicks()
        {
            Application.RemoveMessageFilter(this);
        }

        private void form2ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form2 form2 = new Form2();
            form2.MdiParent = Form1.ActiveForm;
            form2.Show();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Yes");
        }
    }
}

-------------------------
//Form2.cs (Child Form)
-------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace ee_TestCode
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }            

        private void button1_Click(object sender, EventArgs e)
        {
            Form1 f = new Form1();
            f.DisableMouseClicks();
            
            for (int i = 0; i < 1000; i++)
            {
                richTextBox1.Text += i + "|";
            }

            f.EnableMouseClicks();
        }        
    }
}

Open in new window

0
 
LVL 16

Expert Comment

by:Vikram Singh Saini
Comment Utility
Hello @mohd_haq,

Your code line:
UpLoad up = new UpLoad();(this is my childform)
up.ShowDialog();

For this code line I am having some doubts. Please rectify me if I am wrong somewhere.

So UpLoad is the child form and there exists another Form as Form1 (for example). So when user clicks some button or menu in Form1 then opens ChildForm. And child form opens in MDI Form. So when I tried code it gives out exception as, Form that is not a top-level form cannot be displayed as a modal dialog box. Remove the form from any parent form before calling showDialog.

Please let me know is it possible to do the code in that way for the Child Form.

Thanks and Regards,
V.S.Saini

0
 
LVL 9

Expert Comment

by:puru1981
Comment Utility
let us not get into the code above.

The above code has cross references within form1 and form2. form2 is opening form1 and form1 is opening form2. since form2 is not a mdi so you are getting into problem and you are opening again form1 from a child form.

the above code is correct and will work fine.
0
 
LVL 6

Expert Comment

by:mohd_haq
Comment Utility
Hi,
thanks puru1981 for answering on my behalf. Actually i was thinking how to answer that :)
0
 
LVL 16

Expert Comment

by:Vikram Singh Saini
Comment Utility
Hello @puru 1981 & mohd_haq,

Though I already checked the comments by you (puru1981). But at that time I was thinking you are trying to answer to the questioner so I didn't respond the same. But now after mohd_haq comments it is confirmed that it was answer to my question I asked.

I know it's wrong to discuss other thing here. But since the solution is related with questioner problem. So I am getting details about it.

And here is my simple scenario (I read your details but it make me confuse). frmParent is ParentForm (also MDI Container) & frmChild is ChildForm. Since frmChild is ChildForm I declared it as (in frmParent button_click code):

frmChild obj=new frmChild();obj.MdiParent = frmParent.ActiveForm;frmChildObj.ShowDialog();

So executing above piece of code gives out exception as Form  that is not a top-level form cannot be displayed as a modal dialog box.  Remove the form from any parent form before calling showDialog.

Also questioner has mentioned that there are two forms as Parent and Child Form. And if there is parent child form concept there must be MDI Form concept too. But you guys are sayinng, "The above code has cross references within form1 and form2. form2 is  opening form1 and form1 is opening form2. since form2 is not a mdi so  you are getting into problem and you are opening again form1 from a  child form."

So should I think that you are not creating any form as MDI. And what's the mean of bold line in above statement. I don't think I am doing the code as you mentioned.

Thanks and Regards,
V.S.Saini
0
 
LVL 6

Expert Comment

by:mohd_haq
Comment Utility
Hi,
Sorry i didn't get you earlier. You could have described it clearly as you have done your.
So for the answer, any form that the mdi parent form opens a child form, it automatically become the child form mdi parent. you don't need to specify that. so simply try this

frmChild obj=new frmChild();
frmChildObj.ShowDialog();

Not sure why are you getting the error by specifying the MDI Parent property, but you don't need to. Any child form opened from a MDI Parent becomes the child of the MDI Parent.

Hope I am clear enough and that answers your query.

0
 
LVL 16

Expert Comment

by:Vikram Singh Saini
Comment Utility
Hi @mohd_haq,

Please don't mind me if I ask lot to you. Hope you would excuse me for my mistake. Because I believe on practical aspect of code. So I tested your statements and code.

So you said, any form that the mdi parent form opens a child form, it automatically become the child form mdi parent. So you mean to say if I open any form from MDIParentForm, the opened form becomes child form.

(1) But I tested above and I didn't get expected result. Before I share what I get as output, I would like to share little knowledge I am having of MDIParent and child form. So if I execute the following code:

frmChild obj=new frmChild();obj.MdiParent = frmParent.ActiveForm;frmChildObj.Show();

it will open the frmChild within boundary of frmParent (MDIForm). But if you write following code:

frmChild obj=new frmChild();// obj.MdiParent  = frmParent.ActiveForm; (//Code line is comment now)
frmChildObj.Show();
 you will get your child form (which is not actually child form now) open at the specified StartPosition of Form. So it concluded that frmChild is now not child form.

(2) I place the following code in ChildForm as you said it:

private void child_Load(object sender, EventArgs e)
        {
           frmParent obj = new frmParent();

           //MdiChildren returns array of Forms  that represents MDI child form that are parented to frmParent.
            Form[] form = obj.MdiChildren;

            foreach (Form f in form)
            {
                MessageBox.Show(f.Name); //
No output since there doesn't exist any child form
            }
        }    

So it concluded that any form that is opened from MDIParentForm is not ChidForm of it (by default). You need to programatically set it as ChildForm.

Please response back so that I can know if there is some other way of trying the code as you said.

Thanks and Regards,
V.S.Saini

0
 
LVL 6

Expert Comment

by:mohd_haq
Comment Utility
Hi,
May be you are right. Nice point to make. I always though that by default a child form opened from MDI Parent is its child. But may be i am wrong. I have confirmed it now. You need to specify it for it to be a child form of a MDI Parent. Thanks for asking this question.
Coming to the error you are getting when you try to open a new child form from the MDI Parent, I think you should do like this.

private void button1_Click(object sender, EventArgs e) //button in Mdi Parent.
{
Form2 f2 = new Form2();
f2.MdiParent = this; // this pointer refer to current form
f2.Show();
}
what you were doing was using the object of the form1 instead you need to supply the pointer to the open parent form i.e., the this pointer. Try it and i think should answer your query. And RakeshBhandari please update your code also.
0
 
LVL 16

Expert Comment

by:Vikram Singh Saini
Comment Utility
Hi @mohd_haq,

The code I mentioned:

frmChild obj=new frmChild();obj.MdiParent = frmParent.ActiveForm;frmChildObj.Show();
is working fine but I was talking about code:

frmChild obj=new frmChild();obj.MdiParent = this;frmChildObj.ShowDialog();

And it would generate exception. I am discussing all here because of your code:

UpLoad up = new UpLoad();(this is my childform)                              up.ShowDialog();

However I will also request RakeshBhandari to update his comments and views.

Regards,
V.S.Saini
0
 
LVL 9

Expert Comment

by:puru1981
Comment Utility
let us not discuss it again. if you have any concern then please google it or ask your question separately.

the below code works fine for me.
try this.
//form1 mdiparentform


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

namespace MDI
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void newFormToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form2 frm = new Form2();
            frm.ShowDialog();
        }
 
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.menuStrip1 = new System.Windows.Forms.MenuStrip();
            this.newFormToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.menuStrip1.SuspendLayout();
            this.SuspendLayout();
            // 
            // menuStrip1
            // 
            this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.newFormToolStripMenuItem});
            this.menuStrip1.Location = new System.Drawing.Point(0, 0);
            this.menuStrip1.Name = "menuStrip1";
            this.menuStrip1.Size = new System.Drawing.Size(431, 24);
            this.menuStrip1.TabIndex = 1;
            this.menuStrip1.Text = "menuStrip1";
            // 
            // newFormToolStripMenuItem
            // 
            this.newFormToolStripMenuItem.Name = "newFormToolStripMenuItem";
            this.newFormToolStripMenuItem.Size = new System.Drawing.Size(67, 20);
            this.newFormToolStripMenuItem.Text = "New Form";
            this.newFormToolStripMenuItem.Click += new System.EventHandler(this.newFormToolStripMenuItem_Click);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(431, 420);
            this.Controls.Add(this.menuStrip1);
            this.IsMdiContainer = true;
            this.MainMenuStrip = this.menuStrip1;
            this.Name = "Form1";
            this.Text = "Form1";
            this.menuStrip1.ResumeLayout(false);
            this.menuStrip1.PerformLayout();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.MenuStrip menuStrip1;
        private System.Windows.Forms.ToolStripMenuItem newFormToolStripMenuItem;
    }
}

// form2 child form
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace MDI
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

       
    }
}

Open in new window

0
 
LVL 16

Expert Comment

by:Vikram Singh Saini
Comment Utility
Hi @puru1981,

The discussion is concerned with questioner problem. And so I don't think there is something which we are doing out of the questioner interest.

However in your code you called Form2 as child form. You cannot say the form as Child form until it is not having ParentForm.

Check the link:
 http://msdn.microsoft.com/en-us/library/system.windows.forms.form.mdiparent%28VS.80%29.aspx

Regards,
VSS
0
 
LVL 9

Expert Comment

by:puru1981
Comment Utility
MDI can contain only containers like form,menucontrols etc. you can't put buttons or textbox or these type of controls on a mdiform.

mdiforms are used to open the mainforms within the mdi. No child form can have a MDI form which is opened as showdialog. But you can see the same behavior by applying the solution i have provided.

the way you have interacted is totally wrong because you have opened a new form instead of using the parent so the user will be able to go back on the parent form.

the below code should be written like

 Form1 f = new Form1();
            f.DisableMouseClicks();
           
            for (int i = 0; i < 1000; i++)
            {
                richTextBox1.Text += i + "|";
            }

            f.EnableMouseClicks();

 Form1 f =(Form1)this.Parent;
            f.DisableMouseClicks();
           
            for (int i = 0; i < 1000; i++)
            {
                richTextBox1.Text += i + "|";
            }

            f.EnableMouseClicks();

this confusion will be not there if you have written like this.
0
 
LVL 16

Expert Comment

by:Vikram Singh Saini
Comment Utility
Hi @puru1981

The code line:

Form1 f =(Form1)this.Parent; //Parent gets or sets Parent container of the control

On executing above code exception:
Unable to cast object of type 'System.Windows.Forms.MdiClient' to type 'ee_TestCode.Form1'.

So you mentioned correct code but it would be as:

Form1 f = (Form1)this.MdiParent;

Thanks and Regards,
V.S.Saini
0
 
LVL 9

Expert Comment

by:puru1981
Comment Utility
just wanted to give you a way to this so i have written this way i know i should set it MdiParent.

I want you to understand how it works and explore this more.

same functionality can be achieved in many ways. focus to your goal not the way it is implemented until unless it is pain for you.
0
 
LVL 16

Accepted Solution

by:
Vikram Singh Saini earned 500 total points
Comment Utility
Hi @puru1981,

Thanks for your all valuable comments and information you shared with me. And thanks again for clearing all clouds of doubts pertaining to the discussion above. And please excuse me for any type of inconvenience caused by me.

Thanks and Regards,
Vikram
0
 
LVL 2

Author Closing Comment

by:RakeshBhandari
Comment Utility
Good
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Bit flags and bit flag manipulation is perhaps one of the most underrated strategies in programming, likely because most programmers developing in high-level languages rely too much on the high-level features, and forget about the low-level ones. Th…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

7 Experts available now in Live!

Get 1:1 Help Now