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.
Related
I'm trying to get a DataGridView control (on tab control of Form1) to update when I write data to the underlying MS Access database from two other Forms.
I've read a vast number of replies to similar questions here on StackOverflow and all around the internet but the usual responses;
myDataGridView.Update()
and
myDataGridView.Refresh()
don't work.
Neither does
myBindingSource.ResetBindings(false)
or changing the
DataGridView.DataSource
by setting it null and then setting it to myBindingSource.
I've also tried using the
myTableAdpter.Fill(myDataSet)
approach but again absolutely nothing.
It's a WinForms application in C# using VS2017 and a simple "Refresh" button on the tab in Form1.
I'm absolutely baffled so any help would be greatly appreciated.
Thanks for any help
Regards
Matthew
p.s. Here's the current code I have for the Reset Button but it doesn't do anything.
private void button1_Click(object sender, EventArgs e)
{
RefreshDisplay();
}
private void tabControl1_TabIndexChanged(object sender, EventArgs e)
{
RefreshDisplay();
}
private void RefreshDisplay()
{
sacsDataGridView.DataSource = null;
sacsBindingSource4.ResetBindings(false);
sacsDataGridView.DataSource = sacsBindingSource4;
sacsDataGridView.Update();
sacsDataGridView.Refresh();
}
Regards
Matthew
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?
In Visual C++ MFC there is an inbuilt mechanism for setting the menu item states. I am trying to do the same with C# and a WindowsForm object.
I found this which is not quite the same:
Grey out menustrip items when certain forms are open/active/focused
Here is my menu structure:
So, I decided to try this:
private void viewToolStripMenuView_Click(object sender, EventArgs e)
{
zoomExtentsToolStripMenuItem.Enabled = viewCtrl != null;
}
It kind of works. But I am a bit picky. I can see the menu displayed with the item enabled and then I see it change to disabled.
What is the right way to set the menu item states before the menu is displayed? I know this sounds like a simple issue but I can't find the equivalent methodology to ON_UPDATE_COMMAND_UI.
I was using the wrong event handler!
private void viewToolStripMenuView_DropDownOpening(object sender, EventArgs e)
{
zoomExtentsToolStripMenuItem.Enabled = viewCtrl != null;
}
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();
}
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.