Окно WPF максимизируется с фиксированной / ограниченной шириной
В моем окне WPF я установил
Width="300" MinWidth="300" MaxWidth="300"
Когда я максимизирую это окно, оно стыкуется с левой границей экрана с помощью этого, но нижняя часть окна находится под панелью задач Windows 8.
я пытался
public MainWindow()
{
...
this.MaxHeight = System.Windows.SystemParameters.WorkArea.Height;
}
, но это приводит к нескольким пикселям свободного пространства между панелью задач и моим приложением.
Я бы хотел
- иметь фиксированную ширину окна
- пристыковать его к ПРАВИЛЬНОЙ границе
- не закрывать / заходить под панель задач в развернутом состоянии
1 ответ
К сожалению, ваши три требования, кажется, не достижимы, используя только MinWidth, MaxWidth и WindowState.
Но, тем не менее, все еще возможно достичь чего-то подобного. Что вам нужно сделать, это эмулировать развернутое состояние окна. Вам нужно переместить окно в правильное положение, получить нужную высоту и сделать его неподвижным. Первые две части просты, последняя требует более продвинутых вещей.
Начните с того, что у вас есть окно с Width, MaxWidth и MinWidth, установленным в 300, и добавьте обработчик событий в StateChanged.
Width="300" MinWidth="300" MaxWidth="300" StateChanged="MainWindow_OnStateChanged"
И обработчик событий, и вспомогательные методы:
private bool isMaximized;
private Rect normalBounds;
private void MainWindow_OnStateChanged(object sender, EventArgs e)
{
if (WindowState == WindowState.Maximized && !isMaximized)
{
WindowState = WindowState.Normal;
isMaximized = true;
normalBounds = RestoreBounds;
Height = SystemParameters.WorkArea.Height;
MaxHeight = Height;
MinHeight = Height;
Top = 0;
Left = SystemParameters.WorkArea.Right - Width;
SetMovable(false);
}
else if(WindowState == WindowState.Maximized && isMaximized)
{
WindowState = WindowState.Normal;
isMaximized = false;
MaxHeight = Double.PositiveInfinity;
MinHeight = 0;
Top = normalBounds.Top;
Left = normalBounds.Left;
Width = normalBounds.Width;
Height = normalBounds.Height;
SetMovable(true);
}
}
private void SetMovable(bool enable)
{
HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
if(enable)
source.RemoveHook(WndProc);
else
source.AddHook(WndProc);
}
private static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
const int WM_SYSCOMMAND = 0x0112;
const int SC_MOVE = 0xF010;
switch (msg)
{
case WM_SYSCOMMAND:
int command = wParam.ToInt32() & 0xfff0;
if (command == SC_MOVE)
handled = true;
break;
}
return IntPtr.Zero;
}