What's bad about GDI? (I used to do windows but have not been following, I remember that you need to do GetDC and ReleaseDC on a window handle to get the device context and then to release it - in pairs, else...)
It's a graphics API designed for early-1990s needs. It's missing things we expect today like 30-bit colour support and all-VRAM memory (GDI was hardware accelerated but they gimped it in Windows Vista to ensure compatibility with the DWM).
When working with Win32 it just isn't possible to avoid having to use GDI, for example dealing with painting to a window surface Win32 will give you a GDI device context by default - for example, similarly handling Win32 messages like WM_PAINT uses parts of the GDI API. Finally, each process on Windows has a limited number of GDI objects it can use as well. Oh, and using GDI/GDI+ in a service context (e.g. ASP.NET or a Windows Service, is not supported: https://blogs.msdn.microsoft.com/dsui_team/2013/04/16/using-...)
Direct2D is nice - but setting it up in your code isn't easy - and Microsoft does not maintain an up-to-date C#/.NET library for Direct2D.
When working with Win32 it just isn't possible to avoid having to use GDI, for example dealing with painting to a window surface Win32 will give you a GDI device context by default - for example, similarly handling Win32 messages like WM_PAINT uses parts of the GDI API. Finally, each process on Windows has a limited number of GDI objects it can use as well. Oh, and using GDI/GDI+ in a service context (e.g. ASP.NET or a Windows Service, is not supported: https://blogs.msdn.microsoft.com/dsui_team/2013/04/16/using-...)
Direct2D is nice - but setting it up in your code isn't easy - and Microsoft does not maintain an up-to-date C#/.NET library for Direct2D.