0

I have a WinForms control in which some UI elements are drawn with static methods of an internal class - something like this:

internal class DrawUIElement
{
  public static void DrawArrow(Graphics g, Rectangle rect)
  {
    // Drawing something on the Graphics g
  }
}

Now I need to modify this class to support high-res screens. The improved version of the class will draw UI elements depending on the screen resolution. This implies I need to do some calculations based on the screen's current DPI and re-calculate them when the DPI changes. My intention is to use the SystemEvents.DisplaySettingsChanged event for that. I am going to add an event handler in the constructor of the DrawUIElement class and do all required recalculations when the DPI changes in the event handler:

static DrawUIElement()
{
    Microsoft.Win32.SystemEvents.DisplaySettingsChanged += SystemEvents_DisplaySettingsChanged;
}

private static void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)
{
    // Recalculate internal parameters based on the new screen DPI
}

This WinForms control already creates instances of some classes employing the similar SystemEvents.UserPreferenceChanged event. Those classes implement the Dispose() method from the IDisposable pattern to release references to the SystemEvents_UserPreferenceChanged event handler to avoid resource leaking when the form with the control is closed.

The question is: do I also need to add the Dispose() method to my DrawUIElements class that will detach my SystemEvents_DisplaySettingsChanged event handler from SystemEvents.DisplaySettingsChanged to avoid resource leaking or there is no need to worry about this in a class containing only static methods?

TecMan
  • 2,743
  • 2
  • 30
  • 64
  • Dispose() is meant to release a resource early, before the GC gets around to it. You need to listen to that event for the life of the app. That's a feature, not a resource leak. There is no point in disposing anything a millisecond before the app terminates. – Hans Passant Jan 10 '20 at 09:22
  • You will probably get a memory leak if forgot to unsubscribe from static event, during app runtime. But there is no point for disposal actually – Pavel Anikhouski Jan 10 '20 at 09:22
  • @PavelAnikhouski, as I understand, actually we will have just 1 instance of the DrawUIElement class in memory during the lifetime of the app. If I will recalculate some static integer/float fields of the class in the SystemEvents_DisplaySettingsChanged event handler, nothing bad happens - right? – TecMan Jan 10 '20 at 09:35
  • @HansPassant, can this architecture with the SystemEvents_DisplaySettingsChanged event handler always living prevent the visual control from destroying/releasing properly when the form containing it is closed? – TecMan Jan 10 '20 at 09:37
  • @TecMan yes, that's fine. You can get some leaks if forgot to unsubscribe from event, when it's not needed. But it seems that `DisplaySettingsChanged` is needed during all the time of your app lifetime – Pavel Anikhouski Jan 10 '20 at 09:39
  • @PavelAnikhouski, the event is needed while we have an instance of the control on a form. But in the general case an app can have more than one form, and not all forms may contain the control. That's the possible problem. – TecMan Jan 10 '20 at 09:42

0 Answers0