gpt4 book ai didi

wpf - 调整 WPF 窗口的大小,但保持比例?

转载 作者:可可西里 更新时间:2023-11-01 12:34:12 25 4
gpt4 key购买 nike

我有一个用户可调整大小的 WPF 窗口,我想限制调整大小,以便窗口的纵横比保持不变。

理想情况下,我想在调整窗口大小时通过将一个角拖动到保持适当纵横比的位置来限制鼠标位置。如果用鼠标调整边缘的大小,则其他尺寸应同时改变。

是否有任何人都知道的简单方法或一个很好的在线示例?

如果没有更好的解决方案,我会在稍微完善后发布我所做的。

最佳答案

我在 Nir ​​here 找到了一个很好的答案.还是有一些瑕疵,基本上在右上角,右下角和底边调整大小就可以了,其他边和角就不行了。好的一面是,宽高比始终保持平稳。

编辑:我找到了消除大部分问题的方法。当开始调整大小时,将通过定位鼠标相对于窗口的位置来确定将人为调整以保持纵横比的尺寸。我发现的唯一不足之处是,从角落(右下角除外)调整大小时,窗口的位置可能会发生变化。

xaml:

<Window x:Class="WpfApplication1.ConstantAspectRatioWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ConstantAspectRatioWindow" MinHeight="100" MinWidth="150" SizeToContent="WidthAndHeight">
<Grid>
<Border Width="300" Height="200" Background="Navy"/>
<Border Width="150" Height="100" Background="Yellow" />
</Grid>
</Window>

代码隐藏:

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;

namespace WpfApplication1
{
public partial class ConstantAspectRatioWindow : Window
{
private double _aspectRatio;
private bool? _adjustingHeight = null;

internal enum SWP
{
NOMOVE = 0x0002
}
internal enum WM
{
WINDOWPOSCHANGING = 0x0046,
EXITSIZEMOVE = 0x0232,
}

public ConstantAspectRatioWindow()
{
InitializeComponent();
this.SourceInitialized += Window_SourceInitialized;
}

[StructLayout(LayoutKind.Sequential)]
internal struct WINDOWPOS
{
public IntPtr hwnd;
public IntPtr hwndInsertAfter;
public int x;
public int y;
public int cx;
public int cy;
public int flags;
}

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetCursorPos(ref Win32Point pt);

[StructLayout(LayoutKind.Sequential)]
internal struct Win32Point
{
public Int32 X;
public Int32 Y;
};

public static Point GetMousePosition() // mouse position relative to screen
{
Win32Point w32Mouse = new Win32Point();
GetCursorPos(ref w32Mouse);
return new Point(w32Mouse.X, w32Mouse.Y);
}


private void Window_SourceInitialized(object sender, EventArgs ea)
{
HwndSource hwndSource = (HwndSource)HwndSource.FromVisual((Window)sender);
hwndSource.AddHook(DragHook);

_aspectRatio = this.Width / this.Height;
}

private IntPtr DragHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
switch ((WM)msg)
{
case WM.WINDOWPOSCHANGING:
{
WINDOWPOS pos = (WINDOWPOS)Marshal.PtrToStructure(lParam, typeof(WINDOWPOS));

if ((pos.flags & (int)SWP.NOMOVE) != 0)
return IntPtr.Zero;

Window wnd = (Window)HwndSource.FromHwnd(hwnd).RootVisual;
if (wnd == null)
return IntPtr.Zero;

// determine what dimension is changed by detecting the mouse position relative to the
// window bounds. if gripped in the corner, either will work.
if (!_adjustingHeight.HasValue)
{
Point p = GetMousePosition();

double diffWidth = Math.Min(Math.Abs(p.X - pos.x), Math.Abs(p.X - pos.x - pos.cx));
double diffHeight = Math.Min(Math.Abs(p.Y - pos.y), Math.Abs(p.Y - pos.y - pos.cy));

_adjustingHeight = diffHeight > diffWidth;
}

if (_adjustingHeight.Value)
pos.cy = (int)(pos.cx / _aspectRatio); // adjusting height to width change
else
pos.cx = (int)(pos.cy * _aspectRatio); // adjusting width to heigth change

Marshal.StructureToPtr(pos, lParam, true);
handled = true;
}
break;
case WM.EXITSIZEMOVE:
_adjustingHeight = null; // reset adjustment dimension and detect again next time window is resized
break;
}

return IntPtr.Zero;
}
}
}

关于wpf - 调整 WPF 窗口的大小,但保持比例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2471867/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com