Igo*_*cov 11 wpf move maximize drag
我在WPF中的自定义窗口(AllowTransparency,WindowStyle = None)有问题.DragMove()方法效果很好,但是当我最大化窗口,或者它通过Windows 7 Aero Snap自动最大化时,此方法根本不起作用.所以我无法用鼠标拖动来取消窗口并将其状态返回到WindowState.Normal.左右Aero Snap运行良好,我可以快速捕捉和取消窗口.但是当它最大化时,除了Win + Down组合之外没有任何作用.也许有人知道如何解决这个问题,或者我在哪里可以通过工作的Aero Snap功能找到其他方法来实现自定义窗口的正确DragMove?
gro*_*ner 14
这是我的方法.尽量缩短)))
private void InitHeader()
{
var border = Find<Border>("borderHeader");
var restoreIfMove = false;
border.MouseLeftButtonDown += (s, e) =>
{
if (e.ClickCount == 2)
{
if ((ResizeMode == ResizeMode.CanResize) ||
(ResizeMode == ResizeMode.CanResizeWithGrip))
{
SwitchState();
}
}
else
{
if (WindowState == WindowState.Maximized)
{
restoreIfMove = true;
}
DragMove();
}
};
border.MouseLeftButtonUp += (s, e) =>
{
restoreIfMove = false;
};
border.MouseMove += (s, e) =>
{
if (restoreIfMove)
{
restoreIfMove = false;
var mouseX = e.GetPosition(this).X;
var width = RestoreBounds.Width;
var x = mouseX - width / 2;
if (x < 0)
{
x = 0;
}
else
if (x + width > screenSize.X)
{
x = screenSize.X - width;
}
WindowState = WindowState.Normal;
Left = x;
Top = 0;
DragMove();
}
};
}
private void SwitchState()
{
switch (WindowState)
{
case WindowState.Normal:
{
WindowState = WindowState.Maximized;
break;
}
case WindowState.Maximized:
{
WindowState = WindowState.Normal;
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
(要获取screenSize,我使用本机方法)
lee*_*mtu 12
Groaner的解决方案无法在多个监视器设置下正常运行,尤其是在主监视器不是最左侧的情况下.
这是我的解决方案,基于他的正确处理单个或多个显示器设置.在此代码中,'rctHeader'是在XAML中定义的Rectangle.
private bool mRestoreIfMove = false;
public MainWindow()
{
InitializeComponent();
}
private void SwitchWindowState()
{
switch (WindowState)
{
case WindowState.Normal:
{
WindowState = WindowState.Maximized;
break;
}
case WindowState.Maximized:
{
WindowState = WindowState.Normal;
break;
}
}
}
private void rctHeader_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ClickCount == 2)
{
if ((ResizeMode == ResizeMode.CanResize) || (ResizeMode == ResizeMode.CanResizeWithGrip))
{
SwitchWindowState();
}
return;
}
else if (WindowState == WindowState.Maximized)
{
mRestoreIfMove = true;
return;
}
DragMove();
}
private void rctHeader_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
mRestoreIfMove = false;
}
private void rctHeader_MouseMove(object sender, MouseEventArgs e)
{
if (mRestoreIfMove)
{
mRestoreIfMove = false;
double percentHorizontal = e.GetPosition(this).X / ActualWidth;
double targetHorizontal = RestoreBounds.Width * percentHorizontal;
double percentVertical = e.GetPosition(this).Y / ActualHeight;
double targetVertical = RestoreBounds.Height * percentVertical;
WindowState = WindowState.Normal;
POINT lMousePosition;
GetCursorPos(out lMousePosition);
Left = lMousePosition.X - targetHorizontal;
Top = lMousePosition.Y - targetVertical;
DragMove();
}
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetCursorPos(out POINT lpPoint);
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int X;
public int Y;
public POINT(int x, int y)
{
this.X = x;
this.Y = y;
}
}
}
Run Code Online (Sandbox Code Playgroud)
在WPF中,我强烈建议在Window.DragMove之前恢复窗口时使用Control.PointToScreen.PointToScreen还将处理多个显示器设置.这将简化还原到以下内容:
private void OnMouseLeftButtonDown( object sender, MouseButtonEventArgs e )
{
if( e.ClickCount == 2 )
{
if( ResizeMode != ResizeMode.CanResize &&
ResizeMode != ResizeMode.CanResizeWithGrip )
{
return;
}
WindowState = WindowState == WindowState.Maximized
? WindowState.Normal
: WindowState.Maximized;
}
else
{
mRestoreForDragMove = WindowState == WindowState.Maximized;
DragMove();
}
}
private void OnMouseMove( object sender, MouseEventArgs e )
{
if( mRestoreForDragMove )
{
mRestoreForDragMove = false;
var point = PointToScreen( e.MouseDevice.GetPosition( this ) );
Left = point.X - ( RestoreBounds.Width * 0.5 );
Top = point.Y;
WindowState = WindowState.Normal;
DragMove();
}
}
private void OnMouseLeftButtonUp( object sender, MouseButtonEventArgs e )
{
mRestoreForDragMove = false;
}
private bool mRestoreForDragMove;
Run Code Online (Sandbox Code Playgroud)
另一个答案有点晚了,但我的代码更简单,所以我把它放在这里。左右对齐工作得很好,但是当窗口最大化或对齐到屏幕上边界并最大化时,DragMove 方法将不起作用!所以这就是我所做的:
只需在要拖动的元素上处理 Mouse_Down 事件,如下所示:
private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (WindowState == WindowState.Maximized)
{
var point = PointToScreen(e.MouseDevice.GetPosition(this));
if (point.X <= RestoreBounds.Width / 2)
Left = 0;
else if (point.X >= RestoreBounds.Width)
Left = point.X - (RestoreBounds.Width - (this.ActualWidth - point.X));
else
Left = point.X - (RestoreBounds.Width / 2);
Top = point.Y - (((FrameworkElement)sender).ActualHeight / 2);
WindowState = WindowState.Normal;
}
DragMove();
}
Run Code Online (Sandbox Code Playgroud)
我希望它可以帮助某人!
归档时间: |
|
查看次数: |
7036 次 |
最近记录: |