Disposing Wpf User Controls

Disposing WPF User Controls

Interesting blog post here: Dispose of a WPF UserControl (ish)

It mentions subscribing to Dispatcher.ShutdownStarted to dispose of your resources.

WPF user control not being disposed

WPF controls do not implement IDisposable and, hence, don't need to be disposed of.
I believe that you want to say "is not being marked as eligible to garbage collection"

it seems that your problem is related to what is called an event reference.
Some of your living instance (some class you have which is not your window/user control) retains a reference to an event. If you close the Window or UserControl that link still lives on and it is not cleared automatically.

When closing the window/user control you should dereference your event like this

EventName-= methodHandler
or
this.UserControlInstance=null

You may read some interesting pattern here

WPF Control Disposal

If you want to statically reference objects, but without keeping them in-memory, you could always elect for a WeakReference<T>

public partial class MyControl : UserControl
{
private readonly static WeakReference<MyControl> _instance
= new WeakReference<T>(null);

public static MyControl Instance
{
get
{
UserControl result;
if(!_instance.TryGetTarget(out result))
_instance.SetTarget(result = new MyControl());

return result;
}
}
}

This, however, introduces the possibility that, depending on the whims of the GC, you may get the same control after quickly closing and refreshing a page. In such case, you should make sure the Unloaded event triggers a nullification of the instance

// Ensure the instance is cleared when unloading
public void OnUnloaded(object sender, RoutedEventArgs args)
{
_instance.SetTarget(null);
}

and then in your XAML...

<UserControl ...
Unloaded="OnUnloaded">

Will the WPF user Control be Disposed if used inside a Windows Form that will be disposed?

If your WPF UserControl is IDisposable the answer is yes, otherwise no.

In the source code for Dispose method of ElementHost class which hosts a WPF UserControl, you can see this:

IDisposable child = this.Child as IDisposable;
if (child != null)
{
child.Dispose();
}

Which means the Child will be disposed, if it's IDisposable.

Note

WPF doesn't rely on IDisposable interface for resource cleanup. But since the UserControl will be used in a Windows Forms Project in an ElementHost control which supports IDisposable pattern, you can rely on IDisposable pattern if you need to perform some resource clean up. But if it was a WPF project, you should use WPF mechanisms for resource clean up.

At what point I need to do Dispose of my custom WPF User Control?

Typically, in WPF, you don't need to make your controls IDisposable. Unlike Windows Forms, WPF UIElement objects are completely managed, and not (normally) wrapping native handles. As such, they don't need to be disposed, and can be left to the garbage collector.

This is why UserControl does not implement IDisposable.

There are, of course, exceptions. If your class encapsulates anything deriving from HwndHost (such as WebBrowser), for example, you will likely want to make your class IDisposable in order to call Dispose() on the encapsulated control. This is normally only required in interop scenarios (ie: WebBrowser, which interops with the native browser controls).

Event to know usercontrol's disposal?

If you want to know when the garbage collector collects the UserControl use this:

    ~UserControl1()
{
//...
}

If you want to know when the UserControl is unloaded from its parent, use Unloaded event on the userControl

note: unlike a Window, a UserControl can't get closed.

Disposing user control from same usercontrol

In general in WPF, UserControls do not need to be 'disposed'... they do not implement the IDisposable Interface. They do not contain any services or other members that require disposing. A WPF UserControl bears very little resemblance to a WinForms UserControl and the sooner that you stop comparing WPF to WinForms, the better you will learn WPF.

The simple act of removing or replacing a UserControl is enough to release whatever resources it may have taken up. We often to use DataTemplates in WPF to get the Framework to display a UserControl for us:

<DataTemplate DataType="{x:Type ViewModels:UsersViewModel}">
<Views:UsersView />
</DataTemplate>

...

<ContentControl Content="{Binding ViewModel}" />

When doing this, all you need to do to replace a UserControl is this:

ViewModel = new UsersViewModel();


Related Topics



Leave a reply



Submit