none
UserControl open modal form issue

    Question

  • Hello,

    I've notice this strange problem with user control:

    I've a user control (UserControl1) hosted in a form (Form1)...UserControl1 show a second dialog form (Form2): now Form1 is not navigable and this is OK.

    In Form2 there is a button, when I click on it I set Form1 and Form2 NOT enabled, I do a long-time operation and finally set Form1 and Form2 enabled: after I do that Form2 is again top-most but Form1 now is inexplicably navigable and I don't want that!!!

     

    Someone can help me?

    Thanks in advance!!

    Monday, January 23, 2012 8:58 AM

All replies

  • In Form2 there is a button, when I click on it I set Form1 and Form2 NOT enabled, I do a long-time operation and finally set Form1 and Form2 enabled: after I do that Form2 is again top-most but Form1 now is inexplicably navigable and I don't want that!!!

    I think you cannot set both Form1 and Form2 "enabled"——But just use Form2.ShowDialog(),which makes Form1 cannot be used。

    All in all,If you don't want the two windows can be converted by mouse-clicking,you must use ShowDialog()。


       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处
    Monday, January 23, 2012 9:25 AM
  • In Form2 there is a button, when I click on it I set Form1 and Form2 NOT enabled, I do a long-time operation and finally set Form1 and Form2 enabled: after I do that Form2 is again top-most but Form1 now is inexplicably navigable and I don't want that!!!

    I think you cannot set both Form1 and Form2 "enabled"——But just use Form2.ShowDialog(),which makes Form1 cannot be used。

    All in all,If you don't want the two windows can be converted by mouse-clicking,you must use ShowDialog()。


       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处


    Form1 is MdiParent and have I've created public "helper" methods that enable/disable it when I do a long-time operation and shows to the user the description of this operation while waiting.

    When I do a long-time operation in a user control (maybe hosted in dialog form, but maybe not...) I've called however this methods, I noticed only now this problem and before edit the methods in Form1 and everywhere they are called I want to know why there is this issue and an alternative way to resolve it (if there was).

     

    Thanks

     

    Monday, January 23, 2012 9:59 AM
  • Hi terench,

    Welcome to the MSDN Forum.

    If you want to host a form from another form, use Delegate like the following sample:

    https://skydrive.live.com/redir.aspx?cid=0331372fa6a33be3&resid=331372FA6A33BE3!207&parid=331372FA6A33BE3!141 

    or you can sendMessage to all your forms:
    http://msdn.microsoft.com/en-us/library/ms644950.aspx

    Best Regards


    Neddy Ren[MSFT]
    MSDN Community Support | Feedback to us
    Tuesday, January 24, 2012 7:42 AM
  •  Hi Neddy,

    thanks for the reply.

    If you want to host a form from another form, use Delegate like the following sample:

    https://skydrive.live.com/redir.aspx?cid=0331372fa6a33be3&resid=331372FA6A33BE3!207&parid=331372FA6A33BE3!141 

     I tried to edit this project setting MainForm not enabled and after enabled from DialogForm using delegate but the problem occurs again.

    or you can sendMessage to all your forms:
    http://msdn.microsoft.com/en-us/library/ms644950.aspx


    I can't understand how to use this function in my scenario.

     

    Thanks.

    Tuesday, January 24, 2012 8:55 AM
  • Hi terench,

    For the first, I will help you to sendmessage:

    1. create a new Project and create two forms[Form1 and Form2, Form1 is opened default].

    2. In the form 1, drag a button into it and the code as:

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();        
        }
    
        [DllImport("User32.dll")]
        private static extern Int32 SendMessage( IntPtr hWnd, int Msg,  IntPtr wParam,  StringBuilder lParam);
    
        private const int WM_SETTEXT = 0x000C;
        int i = 0;
    
        private void button1_Click(object sender, EventArgs e)
        {
    
            foreach (Form frm in Application.OpenForms)
            {
                if (frm.Name == "Form2")
                {
                    if(i%2 == 0)
                        SendMessage(frm.Handle, WM_SETTEXT, IntPtr.Zero, new StringBuilder("Enabled"));
                    else
                        SendMessage(frm.Handle, WM_SETTEXT, IntPtr.Zero, new StringBuilder("DisEnabled"));
                    i++;
                }
            }
        }
    
        private void Form1_Load(object sender, EventArgs e)
        {            
            Form2 frm = new Form2();
            frm.Name = "Form2";
            frm.Show();
        }
    }
    

    Note: Here I just use WM_SETTEXT as the Message, in default, the WM_SETTEXT message will change the Form2.Text. To know about all the Messages, see: http://www.pinvoke.net/default.aspx/Enums/WindowsMessages.html

    3. In Form2, The code is:

    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();           
        }
    
        private const int WM_SETTEXT = 0x000C;
    
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_SETTEXT)
            {
    
                string s = Marshal.PtrToStringAuto(m.LParam);
    
                if (s == "Enabled")
                    this.Enabled = true;
                else if (s == "DisEnabled")
                    this.Enabled = false;
            }
    
            base.WndProc(ref m);
        }
    }
    

    So, when you click the button in the Form1, the Form2 will change Enabled property automatically.

    Best Regards

     


    Neddy Ren[MSFT]
    MSDN Community Support | Feedback to us
    Wednesday, January 25, 2012 7:12 AM
  • And in my sample, you can open the ChildForm1 and view the code, change the code as follows:

    public partial class ChildForm1 : Form
    {
    
        public ChildForm1()
        {
            InitializeComponent();
        }
    
        public void SetParameterValueCallbackFn(string param)
        {
            if (param.Length % 2 == 0)
            {
                this.Enabled = true;
            }
            else
            {
                this.Enabled = false;
            }
            this.txt_Message.Text = param;
        }
    }
    

    Then, when you enter the text into the MainForm, you will get the screenshot as:

    Best Regards


    Neddy Ren[MSFT]
    MSDN Community Support | Feedback to us
    Wednesday, January 25, 2012 7:23 AM
  • Hi Neddy,

     

    probably not able to explain, my problem is when i change "Enabled" field of a parent form ("Form1" in first example) from his child form ("Form2" in first example) showed as dialog: I'm able to do that but if I set Form1.Enabled = false and after few second set Form1.Enabled = true (always from Form2), Form1 became navigable even if it has a child form showed ad dialog (afted set Form1.Enabled = true,  Form2 is top most but I can however access with the mouse Form1 and this is not right).

     

    Thanks.

     

    Wednesday, January 25, 2012 8:51 AM
  • Hi Neddy,

    probably not able to explain, my problem is when i change "Enabled" field of a parent form ("Form1" in first example) from his child form ("Form2" in first example) showed as dialog: I'm able to do that but if I set Form1.Enabled = false and after few second set Form1.Enabled = true (always from Form2), Form1 became navigable even if it has a child form showed ad dialog (afted set Form1.Enabled = true,  Form2 is top most but I can however access with the mouse Form1 and this is not right).

    Thanks.

    Then, would you please upload a small demon for us so that we can help you and fix it!

    Best Regards


    Neddy Ren[MSFT]
    MSDN Community Support | Feedback to us
    Thursday, January 26, 2012 3:30 AM
  • Hi Neddy,

    Form1 and Form2 contains only "button1", here is the code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Windows.Forms;
    using System.Threading;

    static class Program
    {
       [STAThread]
       static void Main()
       {
          Application.EnableVisualStyles();
          Application.SetCompatibleTextRenderingDefault(false);
          Application.Run(new Form1());
       }
    }

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

       private void button1_Click(object sender, EventArgs e)
       {
          Form2 wForm2 = new Form2(this);
          wForm2.ShowDialog(this);
       }

       public void SetEnabled(bool enabled)
       {
          this.Enabled = enabled;
       }
    }

    public partial class Form2 : Form
    {
       Form1 m_ParentForm;

       public Form2(Form1 parentForm)
       {
          m_ParentForm = parentForm;

          InitializeComponent();
       }

       private void button1_Click(object sender, EventArgs e)
       {
          m_ParentForm.SetEnabled(false);
          this.Enabled = false;

          Thread.Sleep(2000);

          this.Enabled = true;
          m_ParentForm.SetEnabled(true);
       }
    }

    Friday, January 27, 2012 11:23 AM
  • Hi terench,

    See the sample code like this according to your sample:

    Form1:

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Button btn = new Button();
            btn.Text = "show Form2";
            this.Controls.Add(btn);
            btn.Click += new EventHandler(btn_Click);
        }
    
        void btn_Click(object sender, EventArgs e)
        {
            Form1 frm1 = this;
            Form2 frm2 = new Form2(frm1);
            frm2.ShowDialog();
        }
    
        public void SetEnabled(bool enabled)
        {
            if (enabled)
                this.Enabled = true;
            else
                this.Enabled = false;
        }
    }
    

    Form2:

        public delegate void SetOtherFormDelegate(bool enabled);
    
        public partial class Form2 : Form
        {
            private Form1 frm;
    
            private Form2 frm2;
    
            public Form2(Form1 frm1)
            {
                this.frm = frm1;
                InitializeComponent();
                frm2 = this;
    
                Button btn = new Button();
                btn.Text = "Set Enabled/DisEnabled";
                btn.Width = 150;
                this.Controls.Add(btn);
                btn.Click += new EventHandler(btn_Click);
            }
    
            void btn_Click(object sender, EventArgs e)
            {
                new SetOtherFormDelegate(ChangeOtherFormEnabled).Invoke(false);
                Thread.Sleep(2000);
                new SetOtherFormDelegate(ChangeOtherFormEnabled).Invoke(true);
            }
    
            private void ChangeOtherFormEnabled(bool enabled)
            {
                if (enabled == true)
                {
                    frm.Enabled = true;
                    frm2.Enabled = true;
                }
                else
                {
                    frm.Enabled = false;
                    frm2.Enabled = false;
                }
            }
        }
    

    To change the UI and work with Thread.Sleep(...), you will need to use the Delegate to Invoke it. Or the UI thread will be blocked and the UI can not change so fast.

    Best Regards


    Neddy Ren[MSFT]
    MSDN Community Support | Feedback to us

    • Edited by Neddy Ren Monday, January 30, 2012 6:03 AM
    Monday, January 30, 2012 6:02 AM
  • Hi Neddy,

    I tried to test your example, the issue keep again. Click on the button of Form2 change correctly the enabled propriety of the 2 forms, but after do that Form1 became navigable. To understand the issue do that:

    1 - Run the project, click on the button of Form1. Now Form1 and Form2 are showed, if you try to click on Form1 con can't and Form2 "flicker" because Form2 is showed as dialog. OK.

    2 - Click on the button of Form2, Form1 and Form2 became not enabled and after 2 seconds comes back enabled. OK.

    3 - Now if you try to click on Form1 you can do that (for example you can click again on the button of Form1 and show a different instance of Form2). This is not OK!

    Thanks

    Monday, January 30, 2012 10:05 AM
  • 3 - Now if you try to click on Form1 you can do that (for example you can click again on the button of Form1 and show a different instance of Form2). This is not OK!

    If you wan to click the Form1 and show another Form2, how can you show it as a dialog form? You could only show the form2 as a normal form.

    Now I fix the code as:

    Form1:

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Button btn = new Button();
            btn.Text = "show Form2";
            this.Controls.Add(btn);
            btn.Click += new EventHandler(btn_Click);
        }
    
        void btn_Click(object sender, EventArgs e)
        {
            Form2 frm2 = new Form2();
            frm2.Show();
        }
    }
    

    Form2:

    public delegate void SetOtherFormDelegate(bool enabled);
    
    public partial class Form2 : Form
    {
    
        public Form2()
        {
            InitializeComponent();
    
            Button btn = new Button();
            btn.Text = "Set Enabled/DisEnabled";
            btn.Width = 150;
            this.Controls.Add(btn);
            btn.Click += new EventHandler(btn_Click);
        }
    
        void btn_Click(object sender, EventArgs e)
        {
            new SetOtherFormDelegate(ChangeOtherFormEnabled).Invoke(false);
            Thread.Sleep(2000);
            new SetOtherFormDelegate(ChangeOtherFormEnabled).Invoke(true);
        }
    
        private void ChangeOtherFormEnabled(bool enabled)
        {
            foreach (Form frm in Application.OpenForms)
            {
                frm.Enabled = enabled;
            }
        }
    }
    

    Now whatever how many Form2's are opending, click once of the button, all the forms will changes together.

    Best Regards



    Neddy Ren[MSFT]
    MSDN Community Support | Feedback to us
    Wednesday, February 01, 2012 9:05 AM
  • 3 - Now if you try to click on Form1 you can do that (for example you can click again on the button of Form1 and show a different instance of Form2). This is not OK!

    If you wan to click the Form1 and show another Form2, how can you show it as a dialog form? You could only show the form2 as a normal form.

     

    I don't want that user can do that but he can!!! The problem I'm trying to explain is just that: why Form1, that was NOT accessible because has a child form showed as dialog (Form2), after set as NOT ENABLED and re-set as ENABLED became accessible although it still has a child form showed as dialog???
    Wednesday, February 01, 2012 10:37 AM
  • No one can help me to resolve this issue???
    Monday, February 06, 2012 4:00 PM