I need to show up custom messageBox and close it when operation is done.
Problem is messageBox appear normal but without added label wich shows message , i can see only white space...After job is done , messageBox closing work normal.
here is code
public void resetirajSve() {
MyMessageBox poruka = new MyMessageBox();
poruka.Show();
analizaPodataka();
glProstor.Rows.Clear();
poruka.Close();
}
I tried using poruka.ShowDialog() but then code wont to continue executing.. with showDialog method label apper normal...
public partial class MyMessageBox : Form
{
public MyMessageBox()
{
InitializeComponent();
}
}
Some pointers:
1.It seems your custom MessageBox actually inherits a Form. The default MessageBox is rather versatile - see some examples, so there's no need to reinvent the wheel. Focus on more important things.
2.Using ShowDialog() will block all actions from executing on the Form until the newly opened form (you call it MyMessageBox, but it's actually a Form).
3.You could just add a ProgressBar control to display the task's progress and use the wait cursor until it is finished.
4.To avoid the program window becoming unresponsive until the method has finished executing (it can be an issue if it takes a long time), you might want to take a look at asynchronous programming. Here's an example.
Related
I'm working on a console application that creates a form to alert users of some given state - at a later stage, the code base will become a class library.
For now, however, I need to show the form (ShowDialog would be the best method here, I guess) THEN call an arbitrary method before the form closes.
As an example, I need to show the form, set the text value of a label control, wait for n number of seconds, then change the value of the label, then close the form. I know that this sounds a little trivial, but I'm trying to proof-of-concept the design.
I've taken a look around and it doesn't look like this is possible, as ShowDialog() requires me to close the form before I can continue through code listing in the calling method/class.
Here's what I have so far:
PopUpForm myForm = new PopUpForm(string messageToDisplay);
myForm.ShowDialog();
//call myForm.someMethod() here, before the form closes
//dispose of the form, now that we've no use for it
myform.Dispose();
//target method in PopUpform class
public void someMethod()
{
lblText.Text = "Waiting for some reason";
//wait n number of seconds
lblText.Text = "Finished waiting. Form will now close";
//it doesn't matter if the form closes before the user can see this.
}
It looks like ShowDialog() doesn't support this sort of behaviour. I'm looking into BackgroundWorker threads, but was wondering if anyone has any advice on this, or have encountered this before.
If you want to show the form, then continue working, then close it - you can do so via Form.Show() instead of Form.ShowDialog():
using (var myForm = new PopUpForm(messageToDisplay))
{
myForm.Show(); // Show the form
DoWork(); // Do your work...
myForm.Close(); // Close it when you're done...
}
However, if this is purely a console application (and doesn't have a message pump), then this will likely not work properly.
Other options would be to provide a timer within your Form to have it close, or pass a delegate into the Form to run your method on Show, after which it could close itself.
at a later stage, the code base will become a class library.
When you do this, you'll likely want to come up with a different mechanism to provide notifications. Coupling your library to a specific UI technology is a bad idea. It would likely be better to have your library just provide events or other notification, and allow the user to provide the UI/notification to the user.
If this code ie destiend to end up in a code library, I recommend against having it display any forms, ever, of its own volition. The library should generate events, or in some cases exceptions, that can be caught by the invoking application to allow it to display the form. If certain details requiring presentation to the user are internal to the library, expose a DisplayEventData() method from the library.
The ShowDialog-method creates a "modal" window, and usually blocks the UI until you close it (either by clicking OK or Cancel). You would need to create a WinForm yourself, can be a simple one though and create a message-pump for it. You can run your own form by calling
Application.Run(YourForm);
You would need to hold your console-thread with a mutex for example, to keep it from continuing, while the form is open.
The form offers all the methods you know from WinForms like Close, where you could tell your console-thread to continue.
See this on MSDN.
I'm tired and hungry, so I might of missed it, but from what I can see no existing post covers this...
I'm writing a plugin for an application. My plugin loads a form to get some data specifically, it uses the webcam to scan for a barcode. Once it's found a barcode, the form hides itself (incase it's needed again later). This is how I currently call the form that does the barcode work:
string readData = null;
if (eye == null)
{
System.Windows.Forms.Application.EnableVisualStyles();
eye = new CamView();
}
eye.Show();
if (eye.found)
{
readData = eye.readData;
}
return readData;
So, my problem is that eye.show() doesn't block. It makes the form appear and carries right on before there's a chance for the barcode to appear. I imagine I need to use some form of threading or locking, but my crude attempts to do so have just frozen the interface completely.
The "eye" form is basically just a viewfinder for the webcam, and relies on the camera_OnImageCapture event to make it do it's image checks for the barcode.
Is there an elegant way to make the application calling the plugin wait for the form to finish? Or do I just need to add an accept button to the "eye form?"
Cheers. And humble apologies if this is in anyway a repost.
.ShowDialog();
http://msdn.microsoft.com/en-us/library/c7ykbedk.aspx
"You can use this method to display a modal dialog box in your application. When this method is called, the code following it is not executed until after the dialog box is closed."
You are on the right track. You change the code to show CamView as a modal dialog but do no add an Accept button. Instead change camera_OnImageCapture to close the dialog.
I'm having some serious issues with a WinForm application that I'm working on.
Currently, I'm using Form1.ShowDialog(); to display a form. This code is contained in a background worker that looks for changes in a database. Using Form1.ShowDialog(); only allows 1 form to open at a time, even if there are multiple changes to the database. What I want to have happen is for multiple forms to open at once if there is more than one change in my database.
When I use Form1.Show();, the application blows up. For some reason, the Show() method makes the forms not display properly (all the elements in the form are missing).
Is there anything I can do to make my code work the way I want it to?
Edit: here's a code snippet
//result is a linq result
foreach (var row in result)
{
Form1 Form = new Form1();
Form.ShowDialog();
}
After a first look, I can tell you this:
Showdialog can't work the way you intend: this very method makes the owner inactive until the dialog is closed. In your case, the loop will pause at the first showdialog, then resume when you close the form, opening a new one and so on until the loop is finished.
As for the "show" problem, creating empty forms, I need more information. The rest of the code and the exception(s) you're getting.
Two points from the top of my head:
1) To open more then one form , use non modal (modeless) method (i think
the show() method). see for example http://msdn.microsoft.com/en-us/library/39wcs2dh.aspx
2) I am not sure you can call UI related method from a non UI thread. You might want to send an event to your UI thread from the worker thread and the UI thread will call the show method
So I've got some serious problems with removing a Control from a Form of my application. It's kinda messed up but I can't change anything. I have a form and I have a separated user Control. The control opens an exe file and shows a progress bar while loading it's bytes. And here comes the problem. I do all of it with a BackgroundWorker and when the worker_DoWorkerCompleted method is called the original form should show a MessageBox and remove the Control.
BackGround_Loader bgLoad = new BackGround_Loader();
bgLoad.Location = new Point(this.Width/2 - bgLoad.Width/2, this.Height/2 - bgLoad.Height/2);
this.Controls.Add(bgLoad);
bgLoad.BringToFront();
bgLoad.AddReferences(this.executableFile, this.SourceReader);
bgLoad.occuredEvent();
At first I set the control's location to be in the middle of the Form itself. Then I add the control to the form, and bring it to the front. After these I send the path of the executable and a RichTextBox's reference to this. With the occuredEvent I start the BackgroundWorker itself. And here comes my problem. I should show a MessageBox in the Form when the in the bgLoad the backgroundworker gets to the DoWorkerCompleted status. Kindly I have no idea how to do it. It works just perfect however the control stays in the middle of the form.
UI actions must be performed on the main UI thread. The events that get raised from the background worker thread are (obviously) in a different thread.
You need something like the following code:
private void backgroundWorker_DoWork(object sender, AlbumInfoEventArgs e)
{
// Check with an element on the form whether this is a cross thread call
if (dataGridView.InvokeRequired)
{
dataGridView.Invoke((MethodInvoker)delegate { AddToGrid(e.AlbumInfo); });
}
else
{
AddToGrid(e.AlbumInfo);
}
}
In this case AddToGrid is my method for adding a row to a DataGridView, but in your case it will be a method that does what you need to do.
Similarly for the backgroundWorker_RunWorkerCompleted method
See this MSDN example
I could find a way to solve the problem but I don't really like it. In the addReferences method I pass the Form itself and an object of the bgLoad class. Then in the RunWorkerCompleted I check if the control is on the form and if it is then I remove it.
bgLoad.AddReferences(this, bgLoad, this.executableFile, this.SourceReader);
...
private void worker_DoWorkerCompleted(object sender, DoWorkerEventArgs e) {
if(this.MainForm.Controls.Contains(this.Control) {
this.MainForm.Controls.Remove(this.Control);
}
}
Like this it works but it's awful for me.
Short version: I want to trigger the Form_Load() event without making the form visible. This doesn't work because Show() ignores the current value of the Visible property:
tasksForm.Visible = false;
tasksForm.Show();
Long version: I have a WinForms application with two forms: main and tasks. The main form is always displayed. The user can either click a button to open the tasks form, or click some buttons that just run a task directly without opening the tasks form.
When a user asks to run a task directly, I'd like to just call some public methods on the tasks form without showing it. Unfortunately, the task logic depends on stuff that happens in the Form_Load() event. The only way I can find to trigger Form_Load() is to call Show(). The best I've been able to do is to show the form in the minimized state:
tasksForm.WindowState = FormWindowState.Minimized;
tasksForm.Show();
I suppose the cleanest solution would be to pull the tasks logic out of the tasks form and into a controller class. Then I can use that class from the main form and from the tasks form, and only load the tasks form when I need it visible for the user. However, if it's an easy thing to load the form without displaying it, that would be a smaller change.
Perhaps it should be noted here that you can cause the form's window to be created without showing the form. I think there could be legitimate situations for wanting to do this.
Anyway, good design or not, you can do that like this:
MyForm f = new MyForm();
IntPtr dummy = f.Handle; // forces the form Control to be created
I don't think this will cause Form_Load() to be called, but you will be able to call f.Invoke() at this point (which is what I was trying to do when I stumbled upon this SO question).
It sounds to me like you need to sit down and re-think your approach here. I cannot imagine a single reason your public methods need to be in a form if you are not going to show it. Just make a new class.
I totally agree with Rich B, you need to look at where you are placing your application logic rather than trying to cludge the WinForms mechanisms. All of those operations and data that your Tasks form is exposing should really be in a separate class say some kind of Application Controller or something held by your main form and then used by your tasks form to read and display data when needed but doesn't need a form to be instantiated to exist.
It probably seems a pain to rework it, but you'll be improving the structure of the app and making it more maintainable etc.
From MSDN:
Form.Load
Occurs before a form is displayed for the first time.
Meaning the only thing that would cause the form to load, is when it is displayed.
Form.Show(); and Form.Visible = true; are the exact same thing. Basically, behind the scenes, Show checks for various conditions, then sets Visible to true. So obviously, setting visible to false (which it already is) before showing the form is meaningless.
But let's forget the technicalities. I completely agree with Rich B and Shaun Austin - the logic shouldn't be in that form anyway.
Sometimes this would be useful without it being bad design. Sometimes it could be the start of a migration from native to managed.
If you were migrating a c++ app to .NET for example, you may simply make yourwhole app a child window of the .NET form or panel, and gradually migrate over to the .NET by getting rid of your c++ app menu, status bar, toolbar and mapping teh .NEt ones to your app using platform invoke etc...
Your C++ app may take a while to load, but the .NET form doesn't..in which you may like to hide the .NEt form until your c++ app has initialised itself.
I'd set opacity=0 and visible=false to false after calling show, then when your c++ app loads, then reverse.
If you make the method public, then you could access it directly.... however, there could be some unexpected side effects when you call it. But making it public and calling it directly will not draw the screen or open the form.
Move mandatory initialization code for the form class out of the Load event handler into the constructor. For a Form class, instantiation of an instance (via the constructor), form loading and form visibility are three different things, and don't need to happen at the same time (although they do obviously need to happen in that order).
None of the answers solved the original question, so, add the below, call .Show() to load the form without showing it, then call .ShowForm() to allow it to be visible if you want to after:
private volatile bool _formVisible;
protected override void SetVisibleCore(bool value)
{
base.SetVisibleCore(_formVisible);
}
public void ShowForm()
{
_formVisible = true;
if (InvokeRequired)
{
Invoke((Action) Show);
}
else
{
Show();
}
}