WPF 中关于 Screen 的问题(主副屏)

2021-07-12 21:07

阅读:599

标签:require   问题   bsp   private   may   resize   set   rgs   als   

WPF 及 Winform 的 PrimaryScreen 不同用法

https://blog.csdn.net/wzhiu/article/details/7187291

WPF:

this.Top = System.Windows.SystemParameters.WorkArea.Height - this.Height;
this.Left = System.Windows.SystemParameters.WorkArea.Width - this.Width;

Winform:

this.Top = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height - this.Height;
this.Left = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width - this.Width;

 

Show and Maximize WPF window on a specific screen

Question:

I‘m using the following method to display a WPF Window on a specific screen:

private void ShowOnMonitor(int monitor,Window window)
{
    Screen[] screens = Screen.AllScreens;

    window.WindowStyle = WindowStyle.None;
    window.WindowStartupLocation = WindowStartupLocation.Manual;

    window.Left = screens[monitor].Bounds.Left;
    window.Top = screens[monitor].Bounds.Top;
    //window.WindowState = WindowState.Maximized;
    window.Show();
}

The problem is I need the Window to be Maximized to fill the whole screen but as soon as I set:

window.WindowState = WindowState.Maximized;

It keeps showing the Window Maximized but only on the first screen no matter what number I pass through to the ShowOnMonitor() method.

Replies

1. Found the answer for this problem from the below link

http://mostlytech.blogspot.in/2008/01/maximizing-wpf-window-to-second-monitor.html

We cannot maximize the window until the window is loaded when using multiple screens. so hook up a window loaded event and set the window state to Maximized.

private void ShowOnMonitor(int monitor, Window window)
{
    var screen = ScreenHandler.GetScreen(monitor);
    var currentScreen = ScreenHandler.GetCurrentScreen(this);
    window.WindowState = WindowState.Normal;
    window.Left = screen.WorkingArea.Left;
    window.Top = screen.WorkingArea.Top;
    window.Width = screen.WorkingArea.Width;
    window.Height = screen.WorkingArea.Height;
    window.Loaded += Window_Loaded;          
}

/*You can use this event for all the Windows*/
private void Window_Loaded(object sender, RoutedEventArgs e)
{
    var senderWindow = sender as Window;
    senderWindow.WindowState = WindowState.Maximized;
}

ScreenHandler.cs

public static class ScreenHandler
{
    public static Screen GetCurrentScreen(Window window)
    {
        var parentArea = new System.Drawing.Rectangle((int)window.Left, (int)window.Top, (int)window.Width, (int)window.Height);
        return Screen.FromRectangle(parentArea);
    }

    public static Screen GetScreen(int requestedScreen)
    {
        var screens = Screen.AllScreens;
        var mainScreen = 0;
        if (screens.Length > 1 && mainScreen  screens.Length)
        {
            return screens[requestedScreen];
        }
        return screens[0];
    }
}

 

2. I found another post on MSDN which also works:

private void ShowOnMonitor(int monitor,Window window)
{
    Screen[] screens = Screen.AllScreens;

    window.WindowStyle = WindowStyle.None;
    window.WindowStartupLocation = WindowStartupLocation.Manual;

    window.Left = screens[monitor].Bounds.Left;
    window.Top = screens[monitor].Bounds.Top;

    window.SourceInitialized += (snd, arg) => 
        window.WindowState = WindowState.Maximized;

    window.Show();
}

 

3. I am running into what I‘m sure is a problem with an obvious solution but where do I run ShowOnMonitor(monitor,window)? after InitializeComponent() in the MainWindow() class function but that doesn‘t seem to be the case.     I thought I would just need to run ShowOnMonitor(0,MainWindow); but it‘s saying ‘MainWindow is a type not a variable‘ which is true, so I‘m not sure how to access to the current MainWindow. 

EDIT:
Found the solution.  ‘this‘ is the window to pass.   ShowOnMonitor(0,this);
Also I tweaked ScreenHandler.cs:

if (screens.Length > 1 && mainScreen  screens.Length)
{
    if (screens.Length > requestedScreen)
    {
        return screens[requestedScreen];
    }
    else
    {
        return screens[screens.Length - 1];
    }
}

This conditional ensures that the requested monitor is within bounds and avoids a ‘dumb‘ crash in case a config xml or startup flag is malformed. 

 

How to get the size of the current screen in WPF?

https://stackoverflow.com/questions/1927540/how-to-get-the-size-of-the-current-screen-in-wpf

Question:

I know I can get the size of the primary screen by using

System.Windows.SystemParameters.PrimaryScreenWidth;
System.Windows.SystemParameters.PrimaryScreenHeight;

But how do I get the size of the current screen? (Multi-Screen users do not always use the primary screen and not all screens are using the same resolution, right?)

It would be nice to be able to acces the size from XAML, but doing so from code (C#) would suffice.

Answer:

1. I created a little wrapper around the Screen from System.Windows.Forms, currently everything works... Not sure about the "device independent pixels", though.

public class WpfScreen
{
    public static IEnumerable AllScreens()
    {
        foreach (Screen screen in System.Windows.Forms.Screen.AllScreens)
        {
            yield return new WpfScreen(screen);
        }
    }

    public static WpfScreen GetScreenFrom(Window window)
    {
        WindowInteropHelper windowInteropHelper = new WindowInteropHelper(window);
        Screen screen = System.Windows.Forms.Screen.FromHandle(windowInteropHelper.Handle);
        WpfScreen wpfScreen = new WpfScreen(screen);
        return wpfScreen;
    }

    public static WpfScreen GetScreenFrom(Point point)
    {
        int x = (int) Math.Round(point.X);
        int y = (int) Math.Round(point.Y);

        // are x,y device-independent-pixels ??
        System.Drawing.Point drawingPoint = new System.Drawing.Point(x, y);
        Screen screen = System.Windows.Forms.Screen.FromPoint(drawingPoint);
        WpfScreen wpfScreen = new WpfScreen(screen);

        return wpfScreen;
    }

    public static WpfScreen Primary
    {
        get { return new WpfScreen(System.Windows.Forms.Screen.PrimaryScreen); }
    }

    private readonly Screen screen;

    internal WpfScreen(System.Windows.Forms.Screen screen)
    {
        this.screen = screen;
    }

    public Rect DeviceBounds
    {
        get { return this.GetRect(this.screen.Bounds); }
    }

    public Rect WorkingArea
    {
        get { return this.GetRect(this.screen.WorkingArea); }
    }

    private Rect GetRect(Rectangle value)
    {
        // should x, y, width, height be device-independent-pixels ??
        return new Rect
                   {
                       X = value.X,
                       Y = value.Y,
                       Width = value.Width,
                       Height = value.Height
                   };
    }

    public bool IsPrimary
    {
        get { return this.screen.Primary; }
    }

    public string DeviceName
    {
        get { return this.screen.DeviceName; }
    }
}

2. As far as I know there is no native WPF function to get dimensions of the current monitor. Instead you could PInvoke native multiple display monitors functions, wrap them in managed class and expose all properties you need to consume them from XAML.

 

WPF: Multiple screens

https://stackoverflow.com/questions/17859414/wpf-multiple-screens

Question:

I‘m writing a screensaver in WPF. I have the screensaver working, however, it only displays on my main monitor. Is there a way to "black out" or draw graphics to additional monitors when the user has multiple displays? I‘ve done some searching around, but haven‘t found anything relevant.

UPDATE:

From ananthonline‘s answer below, I was able to accomplish the "black out" effect on non-primary displays using the following window:

Window x:Class="ScreenSaver.BlackOut"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Cursor="None" WindowStyle="None" ResizeMode="NoResize" Background="Black">
Window>

and initializing one for each screen in App.xaml.cs using the following process:

foreach (Screen s in Screen.AllScreens)
{
    if (s != Screen.PrimaryScreen)
    {
        BlackOut blackOut = new BlackOut();
        blackOut.Top = s.WorkingArea.Top;
        blackOut.Left = s.WorkingArea.Left;
        blackOut.Width = s.WorkingArea.Width;
        blackOut.Height = s.WorkingArea.Height;
        blackOut.Show();
    }
}

Note an import to System.Windows.Forms is required to access the Screen class.

Answer:

You should be able to use the System.Drawing.Screen.* classes to set up multiple windows on each screen. Mind that you don‘t set each window to be maximized, but a properly sized, border less window.

Also - you might want to remember that the total bounds of the multi monitor setup may not always be a rectangle (if you plan to "union" all the bounds to create a window spanning all monitors).

WPF 中关于 Screen 的问题(主副屏)

标签:require   问题   bsp   private   may   resize   set   rgs   als   

原文地址:https://www.cnblogs.com/xiefang2008/p/9594104.html

上一篇:LC#7

下一篇:C#ORM中的对象映射


评论


亲,登录后才可以留言!