Switching Between Windows WPF (MVC) - c#

I have a test WPF application that has two windows (I'm also using MVC and not MVVM). Both which have one button that should direct the user to the other window.
Initially, I tried this code (I'm only showing the event handlers):
MainWindow.xaml.cs
private static void Button_Click(object sender, RoutedEventArgs e)
{
OtherWindow k = new OtherWindow();
k.Show();
this.Close();
}
OtherWindow.xaml.cs
private static void Button_Click(object sender, RoutedEventArgs e)
{
MainWindow k = new MainWindow();
k.Show();
this.Close();
}
The code works, but I take a look at the memory usage and it increases every time I switch window. Is this normal or is there a way to avoid this and keep the simplicity?

It's very easy to run into memory leaks in WPF, especially when instantiating and disposing of windows multiple times.
I'd recommend taking a look at this page:
http://svetoslavsavov.blogspot.com/2010/05/memory-leaks-in-wpf-applications.html
which details the most common ways to run into a memory leak in WPF and how to fix it.
I'd suggest looking at the Event Handlers and Events from Static Objects sections first.
It seems that you aren't removing your event handlers for your window before closing it, which means that the Window will be kept in memory.
You should also take a look at this thread for good points on disposing of resources correctly. Check out the answer by rookie1024:
What is the correct way to dispose of a WPF window?

Related

WPF application with modal MainWindow

i am wondering if there are any drawbacks, in showing a modal mainwindow in a WPF application with .ShowDialog() instead of Show().
This is the usual way to manually show the mainwindow:
private void Application_Startup(object sender, StartupEventArgs e)
{
// the usual way to show the mainwindow
new MainWindow().Show();
}
This is what i want do to:
private void Application_Startup(object sender, StartupEventArgs e)
{
// what i want to do
new MainWindow().ShowDialog();
}
I want to start a WPF app from a 3. party application addon, that can call static methods from external .NET DLLs. So i build a DLL as an addon that starts my WPF app inside a new AppDomain. This works fine as long the user does not do anything in the 3. party app, otherwise it will crash.
I can prevent this, if i show the mainwindow of my app as a modal dialog, because this blocks the 3. party app window.
Well, a potential drawback is the fact that the ShowDialog() method doesn't return until the dialog window has been closed which means that you won't be able to interact with the "previous" window during the meantime.
But in your case, this seems to be exactly what you want. So since it works the way you want in your specific scenario, I would stick with using ShowDialog().

Minimize Event ( C# Win 8.1 app)

I'm developing an App for windows 8.1 and i need to execute a method to pause some tasks or play a sound when the app is minimized in the sidebar.
I tried:
Application.Current.Suspending += new SuspendingEventHandler(Method_Name);
private void Method_Name(object sender, object e)
{
Other_Method();
}
But this event takes a few seconds (5~10) to occur after I minimize the app.
What event occurs when the app is dragged to the sidebar? What process sends the event?
Thanks.
Check out this post for the answer. It's WindowSizeChanged and check the value of ApplicationView.Value.
[EDIT]
Apparently for 8.1 things have changed a bit. The ApplicationView stuff is deprecated (that was quick) but this still takes place in SizeChanged for the window. Check out this for more details.
After long searching I found something that is not exactly what i wanted, but it works.
This event occurs everytime that visibility of the page changes (Is started, is maximized or minimized for exemple), then you must do some conditions using the if operator.
Window.Current.VisibilityChanged += new WindowVisibilityChangedEventHandler(One_Method);
private void One_Method(object sender, Windows.UI.Core.VisibilityChangedEventArgs e)
{
if(Some_Condition)
{
//TODO: Code that you want execute.
}
}
I'll keep the answer in open for the case of someone knows something more efficient.

How to close a form in UserControl

I created a UserControl with the buttons Save, Close and Cancel. I want to close the form without saving on the Cancel button, prompt a message to save on the Close button and Save without closing on the Save button. Normally, I would have used this.Close() on the Cancel button, but the UserControl doesn't have such an option. So I guess I have to set a property for that.
Scrolling down the "Questions that may already have your answer" section, I came across this question: How to close a ChildWindow from an UserControl button loaded inside it? I used the following C# code:
private void btnCancel_Click(object sender, EventArgs e)
{
ProjectInfo infoScreen = (ProjectInfo)this.Parent;
infoScreen.Close();
}
This does the job for one screen, but I wonder if I have to apply this code for all the screen I have? I think there should be a more efficient way. So my question is: Do I need to apply this code for every form I have, or is there another (more efficient) way?
you can use
((Form)this.TopLevelControl).Close();
you can use the FindForm method available for any control:
private void btnCancel_Click(object sender, EventArgs e)
{
Form tmp = this.FindForm();
tmp.Close();
tmp.Dispose();
}
Do not forget to Dispose the form to release resources.
Hope this helps.
You also can close one form in any part of the code using a remote thread:
MyNamespace.MyForm FormThread = (MyNamespace.MyForm)Application.OpenForms["MyForm"];
FormThread.Close();
I found the simple answer :) I all ready thought of something like that.
To close a WinForm in a ButtonClicked Event inside a UserControl use the following code:
private void btnCancel_Click(object sender, EventArgs e)
{
Form someForm = (Form)this.Parent;
someForm.Close();
}

usercontrol wpf static memory

I'm new to WPF and coming from a C++ background so maybe I'm worry about memory management too much here.
Anyways, I've got a UserControl (NewContact) that has a grid with 2 columns, upper column displays 3 radio buttons and depending on which is selected it loads the appropriate UserControl into the lower section of the grid.
private void newMilitaryContactRadioButton_Checked(object sender, RoutedEventArgs e)
{
UserControl NMC = new NewMilitaryContact();
NewContactWindowGridDisplay.Children.Insert(1, NMC);
}
private void newMilitaryContactRadioButton_Unchecked(object sender, RoutedEventArgs e)
{
NewContactWindowGridDisplay.Children.RemoveAt(1);
}
private void newLegalContactRadioButton_Checked(object sender, RoutedEventArgs e)
{
UserControl NLC = new NewLegalContact();
NewContactWindowGridDisplay.Children.Insert(1, NLC);
}
private void newLegalContactRadioButton_Unchecked(object sender, RoutedEventArgs e)
{
NewContactWindowGridDisplay.Children.RemoveAt(1);
}
private void newFirmContactRadioButton_Checked(object sender, RoutedEventArgs e)
{
UserControl NFC = new NewFirmContact();
NewContactWindowGridDisplay.Children.Insert(1, NFC);
}
private void newFirmContactRadioButton_Unchecked(object sender, RoutedEventArgs e)
{
NewContactWindowGridDisplay.Children.RemoveAt(1);
}
Now my question is whether I should be, and how to, unload the UserControls I create, when a radio button is unchecked. I did some searching around MSDN documentation and saw that the using the remove method from the parent object would unload the usercontrol. If that is the case is the code I'm using to in the various "unchecked" methods correct so as not to pile up a ton of NFC/NLC/NMC UserControl objects if someone were to click amongst the three radio buttons over and over and over again?
Much thanks to anyone to who can explain this to me :)
Actually you need to read more about .Net memory management and know how it works. In your case it depends on what your UserControls are doing? If they are using system resources it will good to dispose their references in UserControl unloaded events, otherwise GC will take care of them.
Read this article :
Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework
Also the way you are going is not so good, because soon you will find out you need to do more with your UserControl like setting its DataContext, Styles handling events and etc... and this will hard to do with code.

WPF webBrowser: how to display to an image after rendering has finished

I have a webBrowser on my UI. I ask if it is possible that it is not displayed directly but instead through an image, and I want that the image is updated only when the LoadCompleted event is received.
How to do?
I'm not sure if I understood your question, but if I did, you basically want to show the loaded web page only when its rendering has finished.
If so, this code should do the trick (I'm assuming you hooked the "LoadCompleted" event up to the "webBrowser1_LoadCompleted" method). This code uses a Button ("button1") to trigger the navigation, but you can use it in any other place.
//here is the code that triggers the navigation: when the button is clicked, I hide the
//webBrowser and then navigate to the page (here I used Google as an example)
private void button1_Click(object sender, RoutedEventArgs e)
{
webBrowser1.Visibility = Visibility.Hidden;
webBrowser1.Navigate(new Uri("http://www.google.it"));
}
private void webBrowser1_LoadCompleted(object sender, NavigationEventArgs e)
{
webBrowser1.Visibility = Visibility.Visible;
}
Keep in mind, though, that not showing anything to the user for a long period of time (as with a heavy page) is not always a good idea, depending on the kind of application you're writing. This is up to you, though.
(I decided to leave the previous answer if someone needs it)
If you want to leave the previous page visible until the new one appears, then I think you need a Windows DLL. This is how I would do it.
At the top of the code file, insert these two import statements:
using System.Runtime.InteropServices;
using System.Windows.Interop;
Then you need to declare your DLL function like this (in the Window class):
[DllImport("user32")]
private static extern int LockWindowUpdate (IntPtr hWnd);
Then, let's modify the code in the previous answer a little bit:
private void button1_Click(object sender, RoutedEventArgs e)
{
IntPtr handle = new WindowInteropHelper(Application.Current.MainWindow).Handle;
LockWindowUpdate(handle);
webBrowser1.Navigate(new Uri("http://www.google.it"));
}
private void webBrowser1_DocumentCompleted(object sender, NavigationEventArgs e)
{
LockWindowUpdate(new IntPtr(0));
}
This should keep the last loaded page on screen until the new page has completed its rendering; as you may imagine, the DLL function simply locks the update of the Window by passing its handle. The handle 0 unlocks it.

Categories

Resources