See the question and my original answer on StackOverflow

It's not super easy to link WinRT classes with GDI/GDI+ classes as WinRT classes don't expose GDI's device name such as \\.\DISPLAY1 which is exposed by Winforms (and can be used from WPF too).

So what you can do is use Connecting and Configuring Displays (CCD) Win32 APIs (BTW this is what WinRT classes use to get monitor's display name, etc. you can also use them to determine if HDR is on/off Windows API to get whether HDR(High Dynamic Range) is active) to determine the GDI device name from an adapter id:

public static string GetGdiDeviceName(int adapterIdHigh, uint adapterIdLow, uint sourceId)
{
    var info = new DISPLAYCONFIG_SOURCE_DEVICE_NAME();
    const int DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME = 1;
    info.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME;
    info.header.size = Marshal.SizeOf<DISPLAYCONFIG_SOURCE_DEVICE_NAME>();
    info.header.adapterIdHigh = adapterIdHigh;
    info.header.adapterIdLow = adapterIdLow;
    info.header.id = sourceId;
    var err = DisplayConfigGetDeviceInfo(ref info);
    if (err != 0)
        throw new Win32Exception(err);

    return info.viewGdiDeviceName;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct DISPLAYCONFIG_SOURCE_DEVICE_NAME
{
    public DISPLAYCONFIG_DEVICE_INFO_HEADER header;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
    public string viewGdiDeviceName;

    public override string ToString() => viewGdiDeviceName;
}

[StructLayout(LayoutKind.Sequential)]
private struct DISPLAYCONFIG_DEVICE_INFO_HEADER
{
    public int type;
    public int size;
    public uint adapterIdLow;
    public int adapterIdHigh;
    public uint id;
}

[DllImport("user32")]
private static extern int DisplayConfigGetDeviceInfo(ref DISPLAYCONFIG_SOURCE_DEVICE_NAME requestPacket);

But this needs a "SourceId", which you can get from WinRT using the IDisplayPathInterop interface

[ComImport, Guid("A6BA4205-E59E-4E71-B25B-4E436D21EE3D"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDisplayPathInterop
{
    [PreserveSig]
    int CreateSourcePresentationHandle(out IntPtr value);

    [PreserveSig]
    int GetSourceId(out uint sourceId);
}

And now you can use all this to dump a maximum number of information for example this C# console app:

static void Main()
{
    using (var mgr = DisplayManager.Create(DisplayManagerOptions.None))
    {
        var state = mgr.TryReadCurrentStateForAllTargets().State;
        foreach (var view in state.Views)
        {
            foreach (var path in view.Paths)
            {
                var monitor = path.Target.TryGetMonitor();
                if (monitor != null)
                {
                    Console.WriteLine(monitor.DisplayName);
                    var ip = (object)path as IDisplayPathInterop;
                    ip.GetSourceId(out var sourceId);
                    var gdiDeviceName = GetGdiDeviceName(monitor.DisplayAdapterId.HighPart, monitor.DisplayAdapterId.LowPart, sourceId);
                    Console.WriteLine(" GDI Name      : " + gdiDeviceName);

                    // use gdiDeviceName to correlate with other APIs such as Screen from Winforms

                    var screen = Screen.AllScreens.FirstOrDefault(s => s.DeviceName == gdiDeviceName);
                    Console.WriteLine(" Is Primary    : " + screen.Primary);
                    Console.WriteLine(" Working Area  : " + screen.WorkingArea);
                    Console.WriteLine();
                }
            }
        }
    }
}

Will output something like this (2 monitors):

DELL U2715H
 GDI Name      : \\.\DISPLAY1
 Is Primary    : False
 Working Area  : {X=2560,Y=0,Width=2560,Height=1392}

C27HG7x
 GDI Name      : \\.\DISPLAY2
 Is Primary    : True
 Working Area  : {X=0,Y=0,Width=2560,Height=1392}