XAML 如何使全屏模式,而不覆盖任务栏使用:wpf c#

rdrgkggo  于 2022-12-07  发布在  C#
关注(0)|答案(7)|浏览(156)

我需要改变我的WPF应用程序中的windows任务栏。为此我设置了WindowStyle="None",这意味着禁用windows任务栏,并使自定义任务栏具有恢复、最小化和关闭应用程序的按钮。现在我的问题是,如果应用程序处于最大化模式,那么我看不到windows上的开始菜单。
我在这里发现了一个类似的问题,但是当我尝试这段代码时,它没有编译。full screen mode, but don't cover the taskbar
如何创建自己的任务栏,并在最大化时看到windows开始菜单?xaml中有属性窗口可以设置它吗?

9jyewag0

9jyewag01#

您可以尝试:

MaxHeight = SystemParameters.MaximizedPrimaryScreenHeight;
MaxWidth = SystemParameters.MaximizedPrimaryScreenWidth;
368yc8dk

368yc8dk2#

通过添加以下内容,可以轻松地在XAML中添加高度约束:

MaxHeight="{Binding Source={x:Static SystemParameters.MaximizedPrimaryScreenHeight}}"

添加到Window的标记中。

0s7z1bwu

0s7z1bwu3#

在CodeProject上找到了一个解决方案,可能会有所帮助:http://www.codeproject.com/Articles/107994/Taskbar-with-Window-Maximized-and-WindowState-to-N

WindowStyle="None"
WindowState="Maximized"
ResizeMode="NoResize"

this.Width = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width;
this.Height = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height;
this.Left = 0;
this.Top = 0;
this.WindowState = WindowState.Normal;
idfiyjo8

idfiyjo84#

WindowStyle="None" 
AllowsTransparency="True"

this.Top = 0;
this.Left = 0;
this.Width = SystemParameters.WorkArea.Width;
this.Height = SystemParameters.WorkArea.Height;
kgqe7b3p

kgqe7b3p5#

建议的解决方案对我有效**,但**仍然需要将像素校正为dpi设置器值,以便窗口具有正确的大小,而不考虑用户设置:
在XAML中:

WindowStyle="None" WindowState="Maximized" ResizeMode="NoResize"

在代码中:

public MainWindow()
{
    InitializeComponent();
    var graphics = System.Drawing.Graphics.FromHwnd(IntPtr.Zero);
    var pixelWidth = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width ;
    var pixelHeight = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height;
    var pixelToDPI = 96.0 / graphics.DpiX ;
    this.Width = pixelWidth * pixelToDPI;
    this.Height = pixelHeight * pixelToDPI;
    this.Left = 0;
    this.Top = 0;
    this.WindowState = WindowState.Normal;
}
z9gpfhce

z9gpfhce6#

I have found a pretty neat solution for the problem in discussion here at the following link, https://codekong.wordpress.com/2010/11/10/custom-window-style-and-accounting-for-the-taskbar/
This works directly out of the box. Just added this here for reference to help anyone in near future.
None of the existing solutions here worked for multiple screens attached in Extended mode.
Pasting the provided solution here to save it from being removed from the blog,
Need to bind SourceInitialized event either from XAML or code behind,

this.SourceInitialized += new EventHandler(Window1_SourceInitialized);

While here's the source code for event callback,

void Window1_SourceInitialized(object sender, EventArgs e)
{
    WindowSizing.WindowInitialized(this);
}

Here's the code for WindowSizing.cs,

using System;
using System.Runtime.InteropServices;
using System.Windows;

namespace OfficeStyleWindowProject
{
   public static class WindowSizing
   {
    const int MONITOR_DEFAULTTONEAREST = 0x00000002;

    #region DLLImports

    [DllImport("shell32", CallingConvention = CallingConvention.StdCall)]
    public static extern int SHAppBarMessage(int dwMessage, ref APPBARDATA pData);

    [DllImport("user32", SetLastError = true)]
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32")]
    internal static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi);

    [DllImport("user32")]
    internal static extern IntPtr MonitorFromWindow(IntPtr handle, int flags);

    #endregion

    private static MINMAXINFO AdjustWorkingAreaForAutoHide(IntPtr monitorContainingApplication, MINMAXINFO mmi)
    {
        IntPtr hwnd = FindWindow("Shell_TrayWnd", null);
        if (hwnd == null) return mmi;
        IntPtr monitorWithTaskbarOnIt = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
        if (!monitorContainingApplication.Equals(monitorWithTaskbarOnIt)) return mmi;
        APPBARDATA abd = new APPBARDATA();
        abd.cbSize = Marshal.SizeOf(abd);
        abd.hWnd = hwnd;
        SHAppBarMessage((int)ABMsg.ABM_GETTASKBARPOS, ref abd);
        int uEdge = GetEdge(abd.rc);
        bool autoHide = System.Convert.ToBoolean(SHAppBarMessage((int)ABMsg.ABM_GETSTATE, ref abd));

        if (!autoHide) return mmi;

        switch (uEdge)
        {
            case (int)ABEdge.ABE_LEFT:
                mmi.ptMaxPosition.x += 2;
                mmi.ptMaxTrackSize.x -= 2;
                mmi.ptMaxSize.x -= 2;
                break;
            case (int)ABEdge.ABE_RIGHT:
                mmi.ptMaxSize.x -= 2;
                mmi.ptMaxTrackSize.x -= 2;
                break;
            case (int)ABEdge.ABE_TOP:
                mmi.ptMaxPosition.y += 2;
                mmi.ptMaxTrackSize.y -= 2;
                mmi.ptMaxSize.y -= 2;
                break;
           case (int)ABEdge.ABE_BOTTOM:
                mmi.ptMaxSize.y -= 2;
                mmi.ptMaxTrackSize.y -= 2;
                break;
            default:
                return mmi;
        }
        return mmi;
    }

    private static int GetEdge(RECT rc)
    {
        int uEdge = -1;
        if (rc.top == rc.left && rc.bottom > rc.right)
            uEdge = (int)ABEdge.ABE_LEFT;
        else if (rc.top == rc.left && rc.bottom < rc.right)
            uEdge = (int)ABEdge.ABE_TOP;
        else if (rc.top > rc.left)
            uEdge = (int)ABEdge.ABE_BOTTOM;
        else
            uEdge = (int)ABEdge.ABE_RIGHT;
        return uEdge;
    }

    public static void WindowInitialized(Window window)
    {
        IntPtr handle = (new System.Windows.Interop.WindowInteropHelper(window)).Handle;
        System.Windows.Interop.HwndSource.FromHwnd(handle).AddHook(new System.Windows.Interop.HwndSourceHook(WindowProc));
    }

    private static IntPtr WindowProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled)
    {
        switch (msg)
        {
           case 0x0024:
                WmGetMinMaxInfo(hwnd, lParam);
                handled = true;
                break;
        }

        return (IntPtr)0;
    }

    private static void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam)
    {
        MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));
        IntPtr monitorContainingApplication = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);

        if (monitorContainingApplication != System.IntPtr.Zero)
        {
            MONITORINFO monitorInfo = new MONITORINFO();
            GetMonitorInfo(monitorContainingApplication, monitorInfo);
            RECT rcWorkArea = monitorInfo.rcWork;
            RECT rcMonitorArea = monitorInfo.rcMonitor;
            mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.left - rcMonitorArea.left);
            mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top);
            mmi.ptMaxSize.x = Math.Abs(rcWorkArea.right - rcWorkArea.left);
            mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top);
            mmi.ptMaxTrackSize.x = mmi.ptMaxSize.x;                                                 //maximum drag X size for the window
            mmi.ptMaxTrackSize.y = mmi.ptMaxSize.y;                                                 //maximum drag Y size for the window
            mmi.ptMinTrackSize.x = 800;                                                             //minimum drag X size for the window
            mmi.ptMinTrackSize.y = 600;                                                             //minimum drag Y size for the window
            mmi = AdjustWorkingAreaForAutoHide(monitorContainingApplication, mmi);                  //need to adjust sizing if taskbar is set to autohide
        }
        Marshal.StructureToPtr(mmi, lParam, true);
    }

    public enum ABEdge
    {
        ABE_LEFT = 0,
        ABE_TOP = 1,
        ABE_RIGHT = 2,
        ABE_BOTTOM = 3
    }

    public enum ABMsg
    {
        ABM_NEW = 0,
        ABM_REMOVE = 1,
        ABM_QUERYPOS = 2,
        ABM_SETPOS = 3,
        ABM_GETSTATE = 4,
        ABM_GETTASKBARPOS = 5,
        ABM_ACTIVATE = 6,
        ABM_GETAUTOHIDEBAR = 7,
        ABM_SETAUTOHIDEBAR = 8,
        ABM_WINDOWPOSCHANGED = 9,
        ABM_SETSTATE = 10
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct APPBARDATA
    {
        public int cbSize;
        public IntPtr hWnd;
        public int uCallbackMessage;
        public int uEdge;
        public RECT rc;
        public bool lParam;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct MINMAXINFO
    {
        public POINT ptReserved;
        public POINT ptMaxSize;
        public POINT ptMaxPosition;
        public POINT ptMinTrackSize;
        public POINT ptMaxTrackSize;
    };

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public class MONITORINFO
    {
        public int cbSize = Marshal.SizeOf(typeof(MONITORINFO));
        public RECT rcMonitor = new RECT();
        public RECT rcWork = new RECT();
        public int dwFlags = 0;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct POINT
    {
        public int x;
        public int y;

        public POINT(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
    }

    [StructLayout(LayoutKind.Sequential, Pack = 0)]
    public struct RECT
    {
        public int left;
        public int top;
        public int right;
        public int bottom;
    }
}
}

~Umar

pengsaosao

pengsaosao7#

WPF解决方案

假设我们想把WPF项目的主窗口放在屏幕的右下角,而不覆盖taskBar,我们可以这样写:

public MainWindow()
    {
        InitializeComponent();
        // set position of window on screen
        this.Left = SystemParameters.PrimaryScreenWidth - this.Width;
        this.Top = SystemParameters.WorkArea.Bottom - this.Height;
    }

this =我们的对象(MainWindow)当我们从PrimarySrceenWidth中减去我们的窗口位置(left)时,我们首先放置left参数。然后,我们做同样的事情,通过从屏幕底部的工作区中减去窗口高度来获得最低点。屏幕的工作区不包括任务栏!
好好享受吧!
阿夫里

相关问题