Windows forms problem - winforms

when I create an application with a form X I use: X->Show(); The application terminates instantly. So I use the X->ShowDialog(); method. Now the UI stops to execute anything after that line. Message boxes will only be shown after I closed the form X, updates and textbox changes won't result in anything...??? How to get rid of this problem? I only want to show a form and change some content of it by user interactions and the user should close it(not the program)...shouldn't it be the easiest thing all over the world when I'm programming Windows programs for Windows with Windows forms? LOL!
int main(array<System::String ^> ^args)
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
Form1^ X = gcnew Form1();
X->ShowDialog();
MessageBox::Show("test", "Warning", MessageBoxButtons::OK);
// message box not shown, only after closing the form...
return 0;
}

Not sure about c++-cli right now but in C# the main form is started and shown in this way:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
so I can be wrong here, but where is your Application.Run ?

What you're trying to do is illogical. You can either ShowDialog() which keeps your program running until the form is closed, or you can keep going through the program and exit immediately. Where do you expect your program to pause? And when do you expect it to close?
The simplest 'solution' to get both on the screen is to reverse the order to:
MessageBox::Show("test", "Warning", MessageBoxButtons::OK);
X->ShowDialog();
then you'll get both on screen. Otherwise run the MessageBox from within the form (in the constructor, OnLoad, wherever).

Related

Closing XNA from Windows Forms

I have a game running in XNA.
In order to create the menus and dialogs I am using windows forms.
My main issue - however, is with my 'Game Over' dialog.
When you die, a message appears asking if you want to try again. When you do - it opens up another instance of xna (so you have two running).
When you select 'Try Again' I would like the first to close and to open a second one.
XNA Game1.cs
GameOver gameover = new GameOver(level, levelManager, kills);
gameover.ShowDialog();
this.Exit();
'GameOver' is the name of the windows form that displays the game over stats.
(This takes the level that the user is on and starts the game at that level)
GameOver.cs (Windows form)
private void button1_Click(object sender, EventArgs e)
{
Visible = false;
Thread thread = new Thread(() =>
{
Game1 game = new Game1(level);
game.Run();
});
thread.Start();
thread.Join();
}
Any help is much appreciated.
i'll sum up the whole thing:
You need to write a reset method that will reset the game window. you can do it by taking all the code in the contractor and put them in another method and call that method in the constructor and in the reset method. make sure you don't leave anything off the reset. any member or connection that need to be initialized.
you can also open a new window and close the current one, but that's not the right way of doing things

Closing (Exiting) and Application before Application.Run() is called?

I'm having trouble understanding how to close an C# .NET winforms application. What I'm trying to do is:
Display a form to allow the user to set-up the environment how they want
If the user presses the "OK" button, perform some logic for setting up the application environment (instantiate objects, etc)
If the user presses "Cancel" or closes the window, close the application.
The problem is, I'm calling the environment set-up form before the main (1st) form. It's a recent requirement change, and I didn't fancy re-writing the code that I have from the very beginning.
The code I have (which should make more sense than my little preamble) is:
public MainForm()
{
InitializeComponent();
//Get the user to set-up the environment (load specific config files, etc)
environmentSetupForm newEnvrionmenSetupForm = new environmentSetupForm ();
if (newEnvrionmenSetupForm .ShowDialog() == DialogResult.OK)
{
newEnvrionmenSetupForm .Close();
//some logic based on what the user selected on the set-up form
}
else
{
//Since the user didn't set-up the environment correctly (there
//was a message box, informing them and giving them another
//shot at it), exit out of the application.
Application.Exit();
}
}
My only problem is that after Application.Exit(), the stack jumps back to Program.cs and performs
Application.Run(new MainForm());
So the Main form (and app) runs regardless. Is there a better way to do what I'm trying to do?
Edit: for clarity my program.cs code reads:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace myNamespace
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
}
}
Neither the form's constructor nor its OnLoad or Load event are good places to put this code. The constructor runs due to the new MainForm() statement in the Main() method, before the Application.Run() call. The Load event is fired because the Application class calls the Show() method, hidden inside the framework code just before Application.Run() enters the message loop. Application.Exit() cannot do anything until that message loop starts running.
The workaround is to move this code to the Main() method in Program.cs. Make it look similar to this:
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
MainForm main;
using (var dlg = new environmentSetupForm()) {
if (dlg.ShowDialog() != DialogResult.OK) return;
// Use dlg values
//...
main = new MainForm();
// Make main form show up at the same location
main.StartPosition = FormStartPosition.Manual;
main.Location = dlg.Location;
}
Application.Run(main);
}
Move the logic from the constructor to the main method.
Since it's related to the start up of the application and not the form it makes sense to have it as part of the start up logic.
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var newEnvrionmenSetupForm = new environmentSetupForm ();
if (newEnvrionmenSetupForm .ShowDialog() == DialogResult.OK) {
newEnvrionmenSetupForm .Close();
//some logic based on what the user selected on the set-up form
var mainform = new MainForm();
Application.Run(mainform);
}
}
Having that kind of logic, especially because it's modal and halts the execution, in a constructor is not a good idea. You want your constructors to be simple initialization of the object and to be repeatable. E.g. if you at some point needed to construct the main form again you wouldn't want the popup at that point in time I guess
Move your code below "InitializeComponent();" to MainForm_Load Event
at Mainform_Load Event instead to do an Application.Exit() just Close() the Form, this should close the app as well.

Reliably Restart a Single-Instance WPF application

I would like to have my current application close and restart. I have seen many posts on this, however none of these seem to work for me.
I have tried
System.Diagnostics.Process.Start(System.Windows.Application.ResourceAssembly.Location);
System.Windows.Application.Current.Shutdown();
However this only restarts the application once. If I press my 'restart' button again (on the already restarted app), it only closes.
I have also tried launching a new System.Diagnostics.Process and closing the current process, but again this does not restart, it simply closes.
How can I restart my current WPF application?
You could create another application which you start when exiting your app and which in return does start your application again. Kind of like how a patcher would work, only without patching anything. On the plus side you could have a loop in that "restart-application" which checks all running processes for your main application process and only tries to re-start it once it does not appear in the process any longer - and you got the bare bones for a patcher also :) Whilst you do not seem to have a problem with restarting your application due to it still being in the processlist - it is the way I would go for when doing it in a production environment as this gives you the most control IMHO.
Edit:
That part in the button event handler (or wherever you want to restart your app with) of your main app (Process2BRestarted.exe in my case):
private void cmdRestart_Click(object sender, EventArgs e)
{
var info = new ProcessStartInfo();
info.FileName = "ProcessReStarter";
info.WindowStyle = ProcessWindowStyle.Hidden;
Process.Start(info);
Application.Exit();
}
This should go into your utility/restarter application (ProcessReStarter.exe over here):
private void MainForm_Load(object sender, EventArgs e)
{
// wait for main application process to end
// really should implement some kind of error-checking/timer here also
while (Process.GetProcessesByName("Process2BRestarted").Count() > 0) { }
// ok, process should not be running any longer, restart it
Process.Start("Process2BRestarted");
// and exit the utility app
Application.Exit();
}
Clicking the restart button will now create a new process ProcessReStarter.exe, which will iterate through the process list of all running processes - checking whether Process2BRestarted is still running. If the process does not appear in the list (any longer) it will now start a new Process2BRestarted.exe process and exit itself.

Wait till winform loads before performing next action?

Winform application contains one form with a reportViewer control. When the form is initialized the report is generated but when I try to programmatically run a PrintDialog on the reportviewer I get a 'Operations is not valid due to the current state of the object' error message.
When I comment out the PrintDialog line the report form shows fine. I think the problem is a lag as it generates the form/report. Is there a way to wait until the form loads before launching the PrintDialog?
Code excerpt:
this.reportViewer1.RefreshReport();
this.reportViewer1.PrintDialog();
UPDATE
Solution is (as suggested):
private void form_load(...)
{
createReport;
this.reportViewer1.RefreshReport();
}
private void reportViewer1_RenderingComplete(...)
{
this.reportViewer1.PrintDialog();
}
This article suggestions you can't/shouldn't call PrintDialog until the RenderingComplete event fires:
http://msdn.microsoft.com/en-us/library/microsoft.reporting.winforms.reportviewer.renderingcomplete(v=vs.80).aspx
http://social.msdn.microsoft.com/Forums/en-US/vsreportcontrols/thread/a8993f3e-7787-4e0a-b32f-fcfbf8df8001/

Control.IsAccessible

I need to check if a c# WinForm Window (FORM Class) has been initialized and waiting for user events. But I could not find out how to manage that.
Therefore I had the idea to set the Control.IsAccessible Flag of the Form to true, within the OnLoad Event of the Windows Form.
My question is now, what is the Control.IsAccessible Flag origin intended for? Or is there an other solution to check if the Winform is initialized.
Thanks for your help
I do not know what IsAccessible is intended for but for the check you are doing you want Created
if(myForm.Created)
{
//Do stuff
}
I had a whole bunch of problems with it, here is one of my old question on SO that helped me out a lot with it.
Control.IsAccessible just means the control is visible to accessibility applications.
You can check myForm.Created to see if the window exists.
You can also register an event handler for the Application.Idle event, which occurs when the application has finished initializing and is ready to begin processing windows messages.
Here is a common usage:
public int Main(string[] args)
{
Application.Idle += WaitUntilInitialized;
}
private void WaitUntilInitialized(object source, EventArgs e)
{
// Avoid processing this method twice
Application.Idle -= WaitUntilInitialized;
// At this point, the UI is visible and waiting for user input.
// Begin work here.
}

Resources