Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C# .NET
I created one child dialog in a thread from my parent dialog and Use the showdialog() method to pop up the dialog. Now the child dialog is going back when we click on parent dialog.
 
But I need stay the dialog on top of the parent dialog as normal when we call showdialog()
 

m_threadStartTest = new Thread(StartTest);
                m_threadStartTest.Start();
 

 
private void StartTest()
       {
           MessageBoxForm obj = new MessageBoxForm();
           obj.ShowDialog();
}
Posted 22-Jan-13 0:33am
Edited 22-Jan-13 0:34am
v2
Comments
adriancs at 24-Jan-13 0:08am
   
I know this problem is solved.
just to share a bit idea.
does this solve your problem too?
at the load event of MessageBoxForm, add this:
this.Activate() or
this.BringToFront() or
this.TopMost = true;
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

You cannot do such things. Moreover, in your case, it makes no sense at all. You need to show dialog in the UI thread. This method you used as a thread start does not contain blocking calls. You had to call it directly.
 
[EDIT #1]
 
However, I realize that you can use the thread for some other reasons. And you may trigger showing this dialog from this already existing thread. In this case you can do this:
class MyForm { 
 
// ...
        void ShowDialogFromAnyThread() {
            System.Action show = new Action(() => {
                new MessageBoxForm().ShowDialog();
            });
            if (InvokeRequired)
                Invoke(show);
            else
                show();
        } //ShowDialogFromAnyThread

} //class MyForm

Here, I also demonstrated how to reuse the show calls with local delegate instance.
You need to use Invoke, not BegingInvoke. I can explain.
 
You should clearly understand that the dialog will be shown in UI thread anyway.
 
[EDIT #2]
 
I also want to explain the role of InvokeRequired. Many excessively use it even it's not needed, and you might also use it. The thing is very simple: this predicate is always false if you call a function like ShowDialogFromAnyThread and always true in case of the call from any other thread. The thread is defined simply: in this context, the "UI thread" is simply the thread when this control (in this case, Form) was created. If calling thread is some other than that, invoke is always required.
 
This way, you can also skip the check via InvokeRequired. If you always call this function from some other thread, you don't need to check, know that invocation is always required.
 
On the invocation mechanism, please see my short article Simple Blocking Queue for Thread Communication and Inter-thread Invocation[^].
 
Please also see my past answers:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].
 
—SA
  Permalink  
v5
Comments
Arun Kumar K S at 23-Jan-13 3:48am
   
In my original code StartTest() doing several processes and showing dialogs during that processes. I don't need to write full code to explain my situation, but with a simple example my question is clear...
Sergey Alexandrovich Kryukov at 23-Jan-13 3:53am
   
I don't say your question is unclear. I insist that you should show you dialog in UI thread and nothing else. After all, just try it.
—SA
Arun Kumar K S at 23-Jan-13 3:59am
   
My child dialogs are showing based on the code in my thread. That I not explained here. I just want to popup my child dialog from thread that will looks like normal model dialog.
Sergey Alexandrovich Kryukov at 23-Jan-13 11:29am
   
Wait a second. I'm started to think that I misunderstood you.
 
Yes, that's possible that you already use a thread for some different reasons and need to show some status using a dialog. This is possible. But this dialog will be shown in UI thread. Yes, in this case you will need invoke...
 
OK, let me take it into account, but this will be just the improvement of the answer you already have.
 
—SA
Sergey Alexandrovich Kryukov at 23-Jan-13 11:44am
   
OK, please see my updated answer, after [EDIT].
 
I want to say: it was my fault; sorry for misunderstanding and possible inconvenience.
 
Even though your explanation was unclear to me, I could take into account this possibility but missed it, so that was my fault.
 
Thank you,
—SA
Arun Kumar K S at 23-Jan-13 23:34pm
   
You are great...
I am giving you 5 and accepting the answer too...
Sergey Alexandrovich Kryukov at 23-Jan-13 23:45pm
   
I tried hard :-) My pleasure that I finally could produce something which could be useful for you.
 
From my side, I'm also thankful for your persistence, when you attempted to convince me that my initial response was incomplete and not yet useful. I always appreciate it.
 
Wish you the best of luck, call again.
—SA
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

You can pass the parent form in your child ShowDialog method as shown below
private void StartTest()
{
  if (InvokeRequired)
  {
    BeginInvoke(new MethodInvoker(StartTest));
    return;
  }
  MessageBoxForm obj = new MessageBoxForm ();
  obj.ShowDialog(parentForm); //Pass your parent form
}
Though this will work for you, it makes no sense as SA mentioned in his solution.
  Permalink  
Comments
Arun Kumar K S at 23-Jan-13 3:40am
   
Thanks...., that worked
Sergey Alexandrovich Kryukov at 23-Jan-13 3:44am
   
Two people are telling you: this makes no sense. No sense at all.
Look at the last clause!
In practice, you should simply call it from UI thread, as I told you. Remove this extra thread or use for something good. You probably think that showing dialog blocks thread until the dialog is closed. No! It returns immediately and only then the dialog is actually shown. Doh!
—SA
Arun Kumar K S at 23-Jan-13 3:52am
   
In my original code StartTest() doing several processes and showing dialogs during that processes. I don't need to write full code to explain my situation, but with a simple example my question is clear...
Sergey Alexandrovich Kryukov at 23-Jan-13 3:41am
   
Yes, formally, it will work correcty, but the fact that it makes no sense is more important. You are not re-using the method StartTest. And also, it's good to pass a parameter to Invoke. Right now you pass it using the Closure (I hope you know closures? Nothing wrong with them, but it's better not to use them without the good reason). What else? It's better to use Action and call StartTest from anonymous method. And, finally, BeginInvoke is redundant; Invoke should better be used...
(I voted 4.)
—SA
Arun Kumar K S at 23-Jan-13 4:17am
   
OK, I will do..,Thanks to your valuable advice and support
Sergey Alexandrovich Kryukov at 23-Jan-13 11:45am
   
Actually, you better use my newly updated answer. I fixed it...
Sorry for inconvenience, probably I missed one important thing, now fixed. That was my fault.
—SA
Sergey Alexandrovich Kryukov at 23-Jan-13 11:47am
   
Please see my solution. I explained what are the improvement from your variants.
I also explained why my "makes no sense" was not correct and explained the case when it actually makes sense, in my [EDIT].
 
I hope OP tried to explain exactly such case, but I failed to see it.
 
—SA

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

  Print Answers RSS
0 OriginalGriff 365
1 Sergey Alexandrovich Kryukov 319
2 CPallini 275
3 DamithSL 214
4 Maciej Los 185
0 OriginalGriff 5,455
1 DamithSL 4,457
2 Maciej Los 3,885
3 Kornfeld Eliyahu Peter 3,480
4 Sergey Alexandrovich Kryukov 3,115


Advertise | Privacy | Mobile
Web02 | 2.8.141216.1 | Last Updated 23 Jan 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100