Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何添加';仅最大化窗户高度';自定义窗口模板的功能_C#_Wpf_Screen_Maximize - Fatal编程技术网

C# 如何添加';仅最大化窗户高度';自定义窗口模板的功能

C# 如何添加';仅最大化窗户高度';自定义窗口模板的功能,c#,wpf,screen,maximize,C#,Wpf,Screen,Maximize,例如,我有下面的代码,用户可以拖动标题栏来移动窗口,或者双击以最大化窗口 private void moveRectangle_PreviewMouseDown(object sender, MouseButtonEventArgs e) { if (Mouse.LeftButton == MouseButtonState.Pressed) DragMove(); if (e.ClickCount == 2) WindowState = (WindowState == WindowS

例如,我有下面的代码,用户可以拖动标题栏来移动窗口,或者双击以最大化窗口

private void moveRectangle_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
   if (Mouse.LeftButton == MouseButtonState.Pressed) DragMove();
   if (e.ClickCount == 2) WindowState = (WindowState == WindowState.Normal) ? WindowState.Maximized : WindowState.Normal;
}
然后我有了这个代码,这样可以拖动窗口边框来调整它的大小

protected void resizeRectangle_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
   Rectangle rectangle = (Rectangle)sender;
   switch (rectangle.Name)
   {
      case "TopSide":
      Cursor = Cursors.SizeNS;
      ResizeWindow(ResizeDirection.Top);
      if (e.ClickCount == 2)
      {
          //Maximize window height here?
      }
      break;
      //Et cetera...
   }
}
但是我还想让用户双击顶部或底部边框,这样窗口的高度就会最大化。我不能在这里使用“Screen.PrimaryScreen.Bounds.Height”或类似的东西。
具体怎么做?

我想您不能使用Screen.PrimaryScreen.Bounds.Height,因为它不包括任务栏的大小

好的,准备好这个答案,因为它有点长。不过,这将根据桌面的可用大小为您提供真正的最大化(即最大化按钮将产生此效果)

本质上,当windows想要调整窗口大小(或最小/最大)时,它会向窗口询问有关窗口大小约束的一些信息。我们在这里做的是给它你想要的约束(在Y上最大化,保持相同的X,并且不改变宽度)


使用制度;
使用系统组件模型;
使用System.Runtime.InteropServices;
使用System.Windows;
命名空间绑定测试
{
公共部分类主窗口:IDisposable,INotifyPropertyChanged
{
公共布尔使能Skinnymode
{
获取{return enableskinymode;}
设置
{
如果(值==enableSkinnyMode)返回;
enableSkinnyMode=值;
OnPropertyChanged(“EnableSkinnyMode”);
}
}
私有布尔使能Skinnymode;
公共主窗口()
{
初始化组件();
this.SourceInitialized+=win\u SourceInitialized;
}
私有无效按钮单击(对象发送者,路由目标)
{
EnableSkinnyMode=EnableSkinnyMode==false;
}
私有void win_SourceInitialized(对象发送方,事件参数e)
{
System.IntPtr handle=(new System.Windows.Interop.WindowInteropHelper(this)).handle;
System.Windows.Interop.HwndSource.FromHwnd(handle.AddHook(WindowProc);
}
private System.IntPtr WindowProc(System.IntPtr hwnd、int msg、System.IntPtr wParam、System.IntPtr lParam、ref bool handled)
{
开关(msg)
{
案例0x0024:/*WM_GETMINMAXINFO*/
如果(启用SkinnyMode)
{
WmGetMinMaxInfo(this、hwnd、lParam);
已处理=正确;
}
打破
}
返回(System.IntPtr)0;
}
公共空间处置()
{
this.SourceInitialized-=win\u SourceInitialized;
System.IntPtr handle=(new System.Windows.Interop.WindowInteropHelper(this)).handle;
System.Windows.Interop.HwndSource.FromHwnd(句柄).RemoveHook(WindowProc);
}
公共事件属性更改事件处理程序属性更改;
受保护的虚拟void OnPropertyChanged(字符串propertyName)
{
PropertyChangedEventHandler处理程序=PropertyChanged;
if(handler!=null)handler(这是新的PropertyChangedEventArgs(propertyName));
}
}
公共类WindowInteropHelper
{
[DllImport(“user32”)]
内部静态外部布尔GetMonitorInfo(IntPtr hMonitor,MONITORINFO lpmi);
[DllImport(“User32”)]
内部静态外部IntPtr监视器FromWindow(IntPtr句柄、int标志);
公共静态void WmGetMinMaxInfo(窗口窗口,System.IntPtr hwnd,System.IntPtr lParam)
{
MINMAXINFO mmi=(MINMAXINFO)Marshal.PtrToStructure(lParam,typeof(MINMAXINFO));
//调整最大尺寸和位置,以适合正确显示器的工作区域
int MONITOR\u DEFAULTTONEAREST=0x00000002;
System.IntPtr monitor=MonitorFromWindow(hwnd,monitor\u DEFAULTTONEAREST);
if(监视器!=System.IntPtr.Zero)
{
MONITORINFO MONITORINFO=新的MONITORINFO();
GetMonitorInfo(监视器,monitorInfo);
RECT rcWorkArea=monitorInfo.rcWork;
RECT rcMonitorArea=monitorInfo.rcMonitor;
mmi.ptMaxPosition.x=(int)window.Left;
//mmi.ptMaxPosition.x=Math.Abs(rcWorkArea.left-rcmonitorrea.left);
mmi.ptMaxPosition.y=Math.Abs(rcWorkArea.top-rcmonitorrea.top);
mmi.ptMaxSize.x=(int)window.Width;
//mmi.ptMaxSize.x=Math.Abs(rcWorkArea.right-rcWorkArea.left);
mmi.ptMaxSize.y=Math.Abs(rcWorkArea.bottom-rcWorkArea.top);
mmi.ptMinTrackSize.x=(int)window.MinWidth;
mmi.ptMinTrackSize.y=(int)window.MinHeight;
}
Marshal.StructureToPtr(mmi,lParam,true);
}
#区域互操作结构
[StructLayout(LayoutKind.Sequential)]
公共结构MINMAXINFO
{
预留公共点;
公共点ptMaxSize;
公共点位置;
公共点的大小;
公共点ptMaxTrackSize;
};
[StructLayout(LayoutKind.Sequential)]
公共结构点
{
/// 
///点的x坐标。
/// 
公共int x;
/// 
///点的y坐标。
/// 
公共智力;
///
<Window x:Class="BindingTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" x:Name="self" DataContext="{Binding ElementName=self}">
    <Grid>
        <Button Click="ButtonClick">
            <Button.Style>
                <Style TargetType="Button">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding EnableSkinnyMode}" Value="True">
                            <Setter Property="Content" Value="Disable Skinny Mode "></Setter>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding EnableSkinnyMode}" Value="False">
                            <Setter Property="Content" Value="Enable Skinny Mode "></Setter>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
        </Button>
    </Grid>
</Window>


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

namespace BindingTest
{
    public partial class MainWindow : IDisposable, INotifyPropertyChanged
    {
        public bool EnableSkinnyMode
        {
            get { return enableSkinnyMode; }
            set
            {
                if (value == enableSkinnyMode) return;
                enableSkinnyMode = value;
                OnPropertyChanged("EnableSkinnyMode");
            }
        }

        private bool enableSkinnyMode;
        public MainWindow()
        {
            InitializeComponent();
            this.SourceInitialized += win_SourceInitialized;
        }

        private void ButtonClick(object sender, RoutedEventArgs e)
        {
            EnableSkinnyMode = EnableSkinnyMode == false;
        }

        private void win_SourceInitialized(object sender, EventArgs e)
        {
            System.IntPtr handle = (new System.Windows.Interop.WindowInteropHelper(this)).Handle;
            System.Windows.Interop.HwndSource.FromHwnd(handle).AddHook(WindowProc);
        }

        private System.IntPtr WindowProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled)
        {
            switch (msg)
            {
                case 0x0024:/* WM_GETMINMAXINFO */
                    if (EnableSkinnyMode)
                    {
                        WindowInteropHelper.WmGetMinMaxInfo(this, hwnd, lParam);
                        handled = true;
                    }
                    break;
            }

            return (System.IntPtr)0;
        }

        public void Dispose()
        {
            this.SourceInitialized -= win_SourceInitialized;
            System.IntPtr handle = (new System.Windows.Interop.WindowInteropHelper(this)).Handle;
            System.Windows.Interop.HwndSource.FromHwnd(handle).RemoveHook(WindowProc);
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public class WindowInteropHelper
    {
        [DllImport("user32")]
        internal static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi);
        [DllImport("User32")]
        internal static extern IntPtr MonitorFromWindow(IntPtr handle, int flags);

        public static void WmGetMinMaxInfo(Window window, System.IntPtr hwnd, System.IntPtr lParam)
        {

            MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));

            // Adjust the maximized size and position to fit the work area of the correct monitor
            int MONITOR_DEFAULTTONEAREST = 0x00000002;
            System.IntPtr monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);

            if (monitor != System.IntPtr.Zero)
            {

                MONITORINFO monitorInfo = new MONITORINFO();
                GetMonitorInfo(monitor, monitorInfo);
                RECT rcWorkArea = monitorInfo.rcWork;
                RECT rcMonitorArea = monitorInfo.rcMonitor;
                mmi.ptMaxPosition.x = (int)window.Left;
                //mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.left - rcMonitorArea.left);
                mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top);
                mmi.ptMaxSize.x = (int)window.Width;
                //mmi.ptMaxSize.x = Math.Abs(rcWorkArea.right - rcWorkArea.left);
                mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top);
                mmi.ptMinTrackSize.x = (int)window.MinWidth;
                mmi.ptMinTrackSize.y = (int)window.MinHeight;
            }

            Marshal.StructureToPtr(mmi, lParam, true);
        }

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

        [StructLayout(LayoutKind.Sequential)]
        public struct POINT
        {
            /// <summary>
            /// x coordinate of point.
            /// </summary>
            public int x;
            /// <summary>
            /// y coordinate of point.
            /// </summary>
            public int y;

            /// <summary>
            /// Construct a point of coordinates (x,y).
            /// </summary>
            public POINT(int x, int y)
            {
                this.x = x;
                this.y = y;
            }
        }
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public class MONITORINFO
        {
            /// <summary>
            /// </summary>            
            public int cbSize = Marshal.SizeOf(typeof(MONITORINFO));

            /// <summary>
            /// </summary>            
            public RECT rcMonitor = new RECT();

            /// <summary>
            /// </summary>            
            public RECT rcWork = new RECT();

            /// <summary>
            /// </summary>            
            public int dwFlags = 0;
        }

        [StructLayout(LayoutKind.Sequential, Pack = 0)]
        public struct RECT
        {
            /// <summary> Win32 </summary>
            public int left;
            /// <summary> Win32 </summary>
            public int top;
            /// <summary> Win32 </summary>
            public int right;
            /// <summary> Win32 </summary>
            public int bottom;

            /// <summary> Win32 </summary>
            public static readonly RECT Empty = new RECT();

            /// <summary> Win32 </summary>
            public int Width
            {
                get { return Math.Abs(right - left); }  // Abs needed for BIDI OS
            }
            /// <summary> Win32 </summary>
            public int Height
            {
                get { return bottom - top; }
            }

            /// <summary> Win32 </summary>
            public RECT(int left, int top, int right, int bottom)
            {
                this.left = left;
                this.top = top;
                this.right = right;
                this.bottom = bottom;
            }


            /// <summary> Win32 </summary>
            public RECT(RECT rcSrc)
            {
                this.left = rcSrc.left;
                this.top = rcSrc.top;
                this.right = rcSrc.right;
                this.bottom = rcSrc.bottom;
            }

            /// <summary> Win32 </summary>
            public bool IsEmpty
            {
                get
                {
                    // BUGBUG : On Bidi OS (hebrew arabic) left > right
                    return left >= right || top >= bottom;
                }
            }
            /// <summary> Return a user friendly representation of this struct </summary>
            public override string ToString()
            {
                if (this == RECT.Empty) { return "RECT {Empty}"; }
                return "RECT { left : " + left + " / top : " + top + " / right : " + right + " / bottom : " + bottom + " }";
            }

            /// <summary> Determine if 2 RECT are equal (deep compare) </summary>
            public override bool Equals(object obj)
            {
                if (!(obj is Rect)) { return false; }
                return (this == (RECT)obj);
            }

            /// <summary>Return the HashCode for this struct (not garanteed to be unique)</summary>
            public override int GetHashCode()
            {
                return left.GetHashCode() + top.GetHashCode() + right.GetHashCode() + bottom.GetHashCode();
            }


            /// <summary> Determine if 2 RECT are equal (deep compare)</summary>
            public static bool operator ==(RECT rect1, RECT rect2)
            {
                return (rect1.left == rect2.left && rect1.top == rect2.top && rect1.right == rect2.right && rect1.bottom == rect2.bottom);
            }

            /// <summary> Determine if 2 RECT are different(deep compare)</summary>
            public static bool operator !=(RECT rect1, RECT rect2)
            {
                return !(rect1 == rect2);
            }
        }

        #endregion
    }
}