WPF如何实现窗口高度自适应内容且禁止手动调整、仅允许调整宽度?
实现WPF窗口高度自适应+禁止手动调整高度但允许调整宽度
核心思路
结合SizeToContent实现高度自适应内容,同时通过拦截Win32窗口消息,精准禁止用户手动调整高度,仅保留宽度调整权限。
步骤实现
1. XAML基础配置
设置窗口属性,开启高度自适应并保留窗口调整能力:
<Window x:Class="WpfApp.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="自适应高度窗口" SizeToContent="Height" ResizeMode="CanResize" MinWidth="300"> <!-- 示例内容,包含Expander控件 --> <StackPanel Margin="10"> <Expander Header="展开查看更多" IsExpanded="False"> <TextBlock Margin="10" TextWrapping="Wrap"> 展开后窗口高度会自动适配内容,用户可拖动左右边框调整宽度,但无法修改高度。 </TextBlock> </Expander> <Button Content="测试按钮" Margin="0 10"/> </StackPanel> </Window>
2. 后台代码拦截调整消息
重写窗口消息处理逻辑,拦截高度调整相关操作:
using System; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Interop; namespace WpfApp { public partial class MainWindow : Window { private const int WM_SIZING = 0x0214; private const int WMSZ_LEFT = 1; private const int WMSZ_RIGHT = 2; [StructLayout(LayoutKind.Sequential)] private struct RECT { public int Left; public int Top; public int Right; public int Bottom; } public MainWindow() { InitializeComponent(); } protected override void OnSourceInitialized(EventArgs e) { base.OnSourceInitialized(e); if (PresentationSource.FromVisual(this) is HwndSource hwndSource) { hwndSource.AddHook(WndProc); } } private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { if (msg == WM_SIZING) { int edge = wParam.ToInt32(); // 仅允许左右边框调整,拦截上下边及四角的高度调整操作 if (edge != WMSZ_LEFT && edge != WMSZ_RIGHT) { var rect = Marshal.PtrToStructure<RECT>(lParam); // 强制保持当前窗口高度不变 rect.Bottom = rect.Top + (int)ActualHeight; Marshal.StructureToPtr(rect, lParam, true); handled = true; } } return IntPtr.Zero; } } }
原理说明
SizeToContent="Height":窗口会自动跟随内部控件(如Expander展开/收缩)的高度变化调整自身高度,无需额外逻辑处理内容适配。WM_SIZING消息拦截:用户拖动窗口边框时系统会发送该消息,通过判断调整的边框类型,若涉及高度变化(上下边、四角),则强制锁定当前高度,仅允许左右边框调整宽度。
内容的提问来源于stack exchange,提问作者Alexander
相关产品推荐
相关产品推荐

