Change Startup Window - c#

I am using Visual Studio 2012 C#. I have created a WPF application project with a main window and added a login window to my project. I want to change the startup window to be my login window but can't seem to do so.
I went to the properties but all I see there is Myproject.app - should it not display the forms of my project?
Anyway I have tried running the window from code as well like so :
Application.Run(new Login());
But that does not seem to work. It gives an error saying :
Error 1 An object reference is required for the non-static field, method, or property 'System.Windows.Application.Run(System.Windows.Window)'

To change startup window update App.xaml by changing Application.StartupUri:
<Application ... StartupUri="MainWindow.xaml">

To change the startup window programmatically go to App.xaml
remove the line StartupUri="MainWindow.xaml" (This will remove the default startup window configuration), now add the startup event Startup="Application_Startup", in App.xaml.cs
private void Application_Startup(object sender, StartupEventArgs e)
{
If(somecase)
{
MainWindow mainWindow = new MainWindow ();
mainWindow.Show();
}
else
{
OtherWindow otherWindow= new OtherWindow();
otherWindow.Show();
}
}

use Application.Current.Run Instead of Application.Run

Related

Unable to Use BreakPoints After Trying to Add Command-Line Support

Update 3
This was actually being caused by a Post-Build action I included which uses ILMerge. See here for more details
Update2
It seems this was not directly caused by adding the command-line support, but I still don't know what did cause it. See SO question for more details.
Update
After making the below changes to allow command-line support, I cannot step through the program with this message on all my breakpoints:
The breakpoint will not currently be hit. No symbols have been loaded for this document
I checked this SO answer and found that I am missing the file Microsoft.VisualStudio.Debugger.Runtime.pdb but I have no idea where it has gone ..
Is there any reason why this would happen because of the App.xaml update?
I have a WPF application for which I need to implement command-line arguments.
Following the answer at this SO question, I amended App.xaml to remove the StartUpUri attribute:
<Application x:Class="WpfFileDeleter.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfFileDeleter"
>
<Application.Resources>
</Application.Resources>
</Application>
I then added an override method to App.xaml.cs:
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
e.Args.Contains("MyTriggerArg")
{
// Do some stuff
}
}
But after inserting a break-point at the top of OnStartUp and debugging the application in Visual Studio, it just hangs in a Ready state but never actually allows me to step through the program.
I tried the following values for StartUpUri:
StartUpUri = "App.xaml"
StartUpUri = "App.xaml.cs"
StartUpUri = "App.xaml.cs.OnStartUp"
But the application just throws a "Cannot locate resource" IOException
According to ethicallogics's answer, it is enough to define startup parameter in
app_start event handler. if you delete starupuri from xaml you need to define somethingelse in sratup handler instead of that
How to start WPF based on Arguments
So App.xaml looks like this:
<Application x:Class="MonitorTool.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MonitorTool"
StartupUri="Views/SplashScreen.xaml"
Exit="Application_Exit">
</Application>
in my App.xaml.cs I got this code:
public partial class App : Application
{
private void Application_Exit(object sender, ExitEventArgs e)
{
//Some settings savin here...
}
}
When you use the XAML way for StartUp make sure the Namespace is right. I got my MainWindow.xaml in a folder called Views.
Or you create the startup like this: Startup="Application_Startup"
and create a Method in the App.xaml.cs file. Again check for namespaces to make sure everything is right here.
Since your app is building I guess this should work and you should at least reach this method.
private void Application_Startup(object sender, StartupEventArgs e)
{
MainWindow window = new MainWindow();
window.Show();
}
Note
When working with arguments you don't need to use the override OnStartup()simply do it like this:
private void Application_Startup(object sender, StartupEventArgs e)
{
string[] args = e.Args;
//Check for some value (for/foreach-loop) and do some stuff
MainWindow w = new MainWindow();
w.Show();
}

Cannot set visibility or call Show, ShowDialog or EnsureHandle after a window has been closed

This is my App constructor for my WPF application:
public partial class App
{
public App()
{
Run(new Login(false));
}
}
And this is my Login constructor:
public Login(bool ignoreSettings)
{
InitializeComponent();
if (ignoreSettings)
{
TxtUsername.Text = SettingsSaver.LoadUsername();
TxtCrmUrl.Text = SettingsSaver.LoadCrmUrl();
return;
}
if (string.IsNullOrWhiteSpace(SettingsSaver.LoadUsername()) || string.IsNullOrWhiteSpace(SettingsSaver.LoadCrmUrl())) return;
try
{
CrmConnector.ConnectToCrm();
MainWindow mainWindow = new MainWindow();
mainWindow.Show();
}
catch (SecurityAccessDeniedException)
{
MessageBox.Show(#"Uw inloggegevens zijn niet correct. Gelieve deze te controleren en opnieuw te proberen.");
}
finally
{
Close();
}
}
It starts the App constructor and goes through the Login constructor just fine, but once it reaches the App Constructor again after finishing the Login constructor, it crashes with an InvalidOperationException, with additional information: "Cannot set visibility or call Show, ShowDialog, or WindowInteropHelper.EnsureHandle after the window has been closed.
The goal of the constructor is as follows: When the application is first started, I want to check if there are existing settings for this application. If they exist, I want to use those settings to connect to a 3rd party (Dynamics CRM 2011), open the main application window, and then close the Login screen. if they are not there, I want the user to set the settings.
HOWEVER, I also want to be able to start this window from a button on my main screen, in which case it should ignore the default settings and launch the login window again, allowing me to set the settings again.
I already managed to get it to work using 2 constructors, but Resharper complains when i does that because I basically ignore the parameter in the second constructor (the one which I launch from the button on the main screen. I'm trying to have 1 unified constructor so Resharper does not complain. Is that possible?
Edit: I don't want to keep my login window because I create a new window when I change the settings, using the following code in my MainWindow:
private void BtnSettings_Click(object sender, RoutedEventArgs e)
{
Login login = new Login(true);
login.Show();
Close();
}
edit: some clarification:
I don't want to show multiple windows. What I want is:
on startup, launch Login.xaml;
when Login.xaml is launched, check if the settings have already been set;
if no settings, show Login.Xaml for setting;
if Settings set, start MainWindow with saved settings.
In addition, I have a button on MainWindow which has to force-start Login.xaml but not check if there are settings. These are currently separate constructors and I would like to make 1 constructor of them.
Your update makes it a bit clearer what it is you want to achieve. I suggest restructuring the Login window to make it more single responsibility and pushing the validation logic up into the App class so that it is responsible for managing initialization flow. A recipe is as follows:
Alter App.Xaml.cs so that it looks something like this; importantly there is no StartupUri:
<Application
x:Class="MyNamespace.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources />
</Application>
Where MyNamespace is the namespace of your App class.
Now you are going to manually start the application from App.OnStartup
public partial class App
{
protected override void OnStartup(System.Windows.StartupEventArgs e)
{
base.OnStartup(e);
if (!AreSettingsSet())
{
this.MainWindow = new Login();
this.MainWindow.ShowDialog(); // Waits until closed.
// Recheck the settings now that the login screen has been closed.
if (!AreSettingsSet())
{
// Tell the user there is a problem and quit.
this.Shutdown();
}
}
this.MainWindow = new MainWindow();
this.MainWindow.Show();
}
private bool AreSettingsSet()
{
// Whatever you need to do to decide if the settings are set.
}
}
To summarise: remove your validation logic from the Login window to App, only show Login if needed and only show MainWindow if the settings are actually valid.
You will need to do some tweaking and then you can show several windows or single window multiple times.
Remove StartupUri from App.xaml.
Set Build action to Page for App.xaml.
This will disable autogenerating of App.g.ics and you can create own application entry point:
public partial class App : Application
{
[STAThread]
public static void Main()
{
App app = new App();
app.InitializeComponent();
app.ShowWindow1();
app.ShowWindow1(); // show second time same window (new instance)
}
public void ShowWindow1()
{
// show window1 in separate method, so that instance will be deleted after method ends
Window1 window1 = new Window1();
// optional (as it seems)
// MainWindow = window1
widow1.Show();
}
}
Try Visibility.Hidden instead of Close if you want to keep it
Update:
this.Visibility=Visibility.Hidden;
I faced a similar challenge,
make sure that any functions that may close the window you are opening are called after the window has loaded.
for the window you are opening set in the xaml file
Loaded="Window_Loaded"
then in the cs file,
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//call your function here
}
This resolved my issue, hope that helps

WPF Window created in Application_Startup method is blank

I have a WPF window in a project with a XAML file and associated C# code behind file. If I set "StartupUri=MainWindow.xaml" in App.xaml to this window the window opens as expected when I start my application.
However, I want my application to to take command line parameters and then decided if it should open the GUI or not. So instead I've set "Startup=Application_Startup" in my App.xaml file which is defined as shown below.
private void Application_Startup(object sender, StartupEventArgs e)
{
if (e.Args.Length > 1)
{
//do automated tasks
}
else
{
//open ui
MainWindow window = new MainWindow();
this.MainWindow = window;
window.Show();
}
}
Yet when I run this the window displayed is totally blank.
Adding window.InitializeComponent() seems to do the trick:
MainWindow window = new MainWindow();
Application.Current.MainWindow = window;
window.InitializeComponent();
window.Show();
I usually like to have a little explanation on why something does or doesn't work. I have no clue in this case. I can see that the examples online don't include InitializeComponent, and yet I produce the same exact error as you do (event without checking for args).
I created a sample application, and removed the StartupUri and set the Startup to the method you provided. Everything seems to work as expected, the content of the window is displayed, so maybe, as Daniel mentioned, you're missing the call to InitializeComponent method in your MainWindow constructor.

MainWindow.ShowDialogue() in a WPF library

I'm accustomed to Winforms where you can create a window and display it via:
Window.ShowDialogue();
I'm using the default MainWindow.xaml in a class library project. I had to delete the App.xaml file to complete the conversion. I want to launch the main window in a simple test. E.G.
[TestMethod]
public void RunPd()
{
MainWindow window = new MainWindow();
window.ShowDialogue();
}
Show/ShowDialogue() is not available. All I have is
GetChildren<>, GetParents<>, InitializeComponent and LoadTree<>.
How can I display MainWindow.xaml?
UPDATE
Main window code:
public partial class MainWindow : Window
Try ShowDialog()
public void RunPd()
{
MainWindow window = new MainWindow();
window.ShowDialog();
}
I'm not sure if this could be the issue or not (your question is a bit vague); however, right-click on the xaml file in the VisualStudio project and click on Properties. Then make sure that "Build Action" is set to "Page."
If this is already set, please make a comment as to that as well.
I had to add a reference to WindowsBase.dll, System.Xaml, PrentationationCore and PrentationFramework. Once I added these references the unit test worked.
Curious as to why I did not need to add these assemblies in Winforms...?

Multiple calls of Application.Run in WPF

I'm trying to run a window, close it, and then run a second window, in a similar way that seems to work with Windows Forms.
namespace WpfApplication1
{
public partial class App : Application
{
[STAThread]
public static void Main()
{
Application app = new Application();
//windowMain.Show();
app.ShutdownMode = ShutdownMode.OnExplicitShutdown;
MainWindow windowMain = new MainWindow();
app.Run(windowMain);
Window1 window1 = new Window1();
window1.Show();
app.Run(window1);
}
}
}
I've set the Build Action in the App.xaml properties from ApplicationDefinition to Page, but the programme throws an exception when window1 is initialised. What am I doing wrong?
Edit: I've modified the xaml in App.xaml as suggested by first answer and edited main as suggested by the comment.
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml"
ShutdownMode="OnExplicitShutdown">
<Application.Resources>
</Application.Resources>
</Application>
but I'm still getting the exception.
OK this is what I've divined so far. The Solution Builder looks for a Main() function. Why its not a WinMain() function I'm still not a hundred per cent clear on. If there is no Main(), you get an error. You can have more than one Main() as long as the Project properties: "Application" page/tab: property: "StartUp Object" is set to point to one of the main()s. This is done from an automatically created drop down list.
When a “WPF Application” project is created, Visual Studio(VS) create an xaml file called “App.xaml”. This is a class declaration where “App” is derived from the “Application” Class. VS also automatically generates hidden files for an xaml file. It creates a “name.g.i.cs” file, when the xaml file is created. It creates a “name.g.cs” file the first time the project is built after the creation of the xaml file. In this case it creates “App.g.cs” and “App.g.i.cs”. These files are hidden by default. To view them, press the “Show all files” button at the top of the Solution Explorer, they can be found in “\ obj\86\Debug” folder. When you delete an xaml file the “name.g.i.cs” and the “name.g.cs” files remain and are not deleted.
The “App.xaml” file’s “build Action” property is set to “Application Definition” when created by VS. When this property is set to “Application Definition” a Main() function is automatically created in “name.g.i.cs”:
[System.STAThreadAttribute()]
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static void Main()
{
WpfApplication8.App app = new WpfApplication8.App();
app.InitializeComponent();
app.Run();
}
When this property is set to “Page”, the Main() function is automatically removed by VS. You can create new “Application” derived classes in code or in xaml. I haven’t found a neat way to do it in xaml. There doesn’t seem to be a template for an xaml “Application” derived class. I created a “.cs” code file and then renamed it to an .xaml file. For some reason VS won’t allow you to have more than one xaml “Application” declaration file set to “Application Build”, it doesn’t even give you the option of choosing one in the "Project: Properties: Application": “Startup Object” property.
As you can see in the hidden Main(), an instance of “App” is instantiated and run. If using your own Main() function: an instance of, the base “Application” class, or an “Application” derived class (whether declared in code or in xaml), can be declared and run. The “Application” class should only be instantiated once and should only be run once. If the “Application” derived class is declared in xaml then a simple application can be run by using the StartUpUri property in the xaml file: StartupUri="Windowname.xaml". Alternatively the top level UI programme logic can be placed in a Startup event handler. If “Startup="Application_Startup" is placed in the “App.xaml” file then an event handler can be written:
private void Application_Startup(object sender, StartupEventArgs e)
{
MainWindow windowMain = new MainWindow();
windowMain.ShowDialog();
Window1 window1 = new Window1();
window1.ShowDialog();
Shutdown();
}
You have to use ShowDialog() here, because it blocks until the window is closed. If you used Show() instead, it would show one window, then immediately show the other one and shutdown the application. In this case there's no need to call the Run() method yourself, that's done automatically.
The “Application” class instance can be run in code whether its declared in code or in xaml. You can then perform initialisation code prior to calling Run(). This would be placed in the Application_ Startup() event handler using the other way. However, if the “Application.Run” call is ever made in the programme, then no windows should be opened (using show() or ShowDialog()) in Main() or anywhere outside of the Application Class or within events and functions called from those events, called during “Application.Run()”.
The Application class has a ShutdownMode property (Application.ShutdownMode). The default for this is: “OnMainWindowClose”. This property can also be set to “OnLastWindowClose” or “OnExplicitShutdown” in code or in the xaml. You will need to reset this if you don't want the programme to close down when the MainWindow is closed.
I think for my purposes it is better not to use the Application class at all and just call the windows using Show() and “ShowDialog()”. This way I can use WPF pages but I could also call Windows Forms, or DirectX screens, as long as they are not open at the same time, or have no UI at all, if the programme is running remotely. Is there any reason for not doing it this way?
I think your application is shuting down when you close the first window. You need to set Application.ShutdownMode to OnExplicitShutdown.
If all you want to do is to show one window, when that closes, show another and when that closes, shutdown the whole application, you should keep the Build action as ApplicationDefinition, set ShutdownMode to OnExplicitShutdown (probably in App.xaml, but you can it in code-behind too) and put the following code in an event handler of the Startup event of your application:
private void Application_Startup(object sender, StartupEventArgs e)
{
MainWindow windowMain = new MainWindow();
windowMain.ShowDialog();
Window1 window1 = new Window1();
window1.ShowDialog();
Shutdown();
}
You have to use ShowDialog() here, because it blocks until the window is closed. If you used Show() instead, it would show one window, then immediatelly show the other one and shutdown the application.
There's no need to run the Run() method yourself, that's done automatically.

Categories