如何在双击标题时禁用最大化WPF窗口并保持调整大小可用?
我知道 ResizeMode 会禁用最大化,但也会阻止调整表单大小
ResizeMode="CanMinimize"
我知道如何删除最大化和最小化按钮,但仍然可以通过双击标题来最大化。
在WinForms中,它可以轻松实现。只需将 FormBorderStyle 从无设置为 FixedSingle 或 Fixed3D 。但它不再是WPF中的一个选项了。
P.S。我正在尝试处理WM_GETMINMAXINFO,WM_SYSCOMMAND等的一些技巧但是seems it's not working ......
答案 0 :(得分:7)
我有类似的问题。我的窗口没有任何表格边框或标题栏,但它可以移动(使用鼠标)。问题是,如果用户将窗口移动到屏幕的上边缘,则Windows会自动最大化窗口。
我设法通过将以下处理程序附加到窗口的StateChanged
事件来解决此问题。
private void OnWindowStateChanged(object sender, EventArgs e)
{
if (this.WindowState == WindowState.Maximized)
{
this.WindowState = WindowState.Normal;
}
}
答案 1 :(得分:6)
很好的解决方案我在MSDN上帮助检测WPF窗口中的非客户端鼠标活动。
handled = true
如果WndProc
调用msg == WM_NCLBUTTONDBLCLK
,则会阻止窗口在用户双击非客户区域时最大化。
myClass() //c'tor
{
InitializeComponent();
SourceInitialized += new EventHandler(myClass_SourceInitialized);
}
void myClass_SourceInitialized(object sender, EventArgs e)
{
System.Windows.Interop.HwndSource source = System.Windows.Interop.HwndSource.FromHwnd(new System.Windows.Interop.WindowInteropHelper(this).Handle);
source.AddHook(new System.Windows.Interop.HwndSourceHook(WndProc));
}
int WM_NCLBUTTONDBLCLK { get { return 0x00A3; } }
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == WM_NCLBUTTONDBLCLK)
{
handled = true; //prevent double click from maximizing the window.
}
return IntPtr.Zero;
}
答案 2 :(得分:2)
WPF 没有以原生方式禁用最大化窗口(与 WinForms 不同)。因此,请考虑以下要点:
<强> 1。隐藏最大化按钮
使用 WinAPI 是一种方法,但仅用于隐藏“最大化”按钮。使用以下内容:
[DllImport("user32.dll")]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
private const int GWL_STYLE = -16;
private const int WS_MAXIMIZEBOX = 0x10000;
private void Window_SourceInitialized(object sender, EventArgs e)
{
var hwnd = new WindowInteropHelper((Window)sender).Handle;
var value = GetWindowLong(hwnd, GWL_STYLE);
SetWindowLong(hwnd, GWL_STYLE, (int)(value & ~WS_MAXIMIZEBOX));
}
<强> 2。手动处理最大化
上面的代码仍允许最大化(例如,双击窗口的标题)。
WPF 无法控制标题栏行为。如果要更改双击行为,则需要删除标题栏并创建自己的标题栏。看看它是如何在MahApps.Metro - link to sample中完成的。之后处理双击事件。
答案 3 :(得分:2)
在遇到这个问题并研究这个问题后,我认为答案是不够的。删除标题栏后,当双击靠近窗口顶部时,窗口仍会最大化。
我选择了删除标题栏并禁用双击窗口的方法。
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
MouseDoubleClick += (sender, args) =>
{
args.Handled = true;
};
}
}
在我的应用程序中,我使用的是MahApps.Metro,它将继承自 MetroWindow 而不是 Window ,但上述示例在两种情况下都适用。
答案 4 :(得分:1)
这对你有用吗?
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.SizeChanged += MainWindow_SizeChanged;
}
void MainWindow_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (this.WindowState == WindowState.Maximized)
{
this.WindowState = System.Windows.WindowState.Normal;
}
}
}
答案 5 :(得分:0)
另一个简单(但丑陋)的解决方案:
// inside a Window class
protected override void OnPreviewMouseDoubleClick(MouseButtonEventArgs e)
{
base.OnPreviewMouseDoubleClick(e);
const int titleHeight = 30;
var position = e.GetPosition(this);
if (position.Y <= titleHeight)
{
e.Handled = true;
}
}
注意:用户仍然可以使用标题栏上的上下文菜单/将窗口移动到屏幕的上边缘来最大化窗口。