我有一个WindowContainer
课程,其中所有ChildWindows
都会自动注册。我们的想法是,所有ChildWindows
都被“锁定”在WindowContainer
内,您无法将其移动/拖动到此区域之外。
ChildWindow
继承自Window
。
我已经找到了解决方案:
// Events
private void ChildWindow_OnLocationChanged(object sender, EventArgs eventArgs)
{
_CheckBounds(sender as HtChildWindow);
}
private void ChildWindow_OnSizeChanged(object sender, SizeChangedEventArgs sizeChangedEventArgs)
{
_CheckBounds(sender as HtChildWindow);
}
// Private Methods
private void _CheckBounds(HtChildWindow window)
{
Rect trueWindowContainer = WindowContainer.TransformToAncestor(System.Windows.Application.Current.MainWindow).TransformBounds(new Rect(new Point(0, 0), WindowContainer.RenderSize));
if (window.Left < trueWindowContainer.X)
window.Left = trueWindowContainer.X;
if (window.Top < trueWindowContainer.Y)
window.Top = trueWindowContainer.Y;
if (window.Left + window.ActualWidth > trueWindowContainer.X + trueWindowContainer.Width)
window.Left = (trueWindowContainer.X + trueWindowContainer.Width) - window.ActualWidth;
if (window.Top + window.ActualHeight > trueWindowContainer.Y + trueWindowContainer.Height)
window.Top = (trueWindowContainer.Y + trueWindowContainer.Height) - window.ActualHeight;
}
问题是,Window仍然可以移动到该区域之外并且它是滞后的。我想通过锁定垂直或水平移动来避免这种行为。
我的解决方案方法是抓住PreviewMouseMove
或PreviewDragMove
事件。但我不知道该怎么做。 PreviewDragMove
不存在。
// ##############################################################################################################################
// Properties
// ##############################################################################################################################
/// <summary>
/// True when when mouse is down on the dragmove area
/// </summary>
public bool IsMouseDownOnDrag { get; private set; }
private Rectangle _PartDragMove;
private Point _AnchorPoint;
private bool _IsDragging;
private Rect _DragMoveArea = Rect.Empty;
// ##############################################################################################################################
// Konstructor
// ##############################################################################################################################
private HtChildWindow()
{
Unloaded += _OnUnloaded;
Loaded += _OnLoaded;
}
private void _OnLoaded(object sender, RoutedEventArgs routedEventArgs)
{
if(_DragMoveArea == Rect.Empty)
_DragMoveArea = SystemParameters.WorkArea;
}
private void _OnUnloaded(object sender, RoutedEventArgs routedEventArgs)
{
if (_PartDragMove != null)
{
_PartDragMove.PreviewMouseLeftButtonDown -= PartDragMove_OnPreviewMouseLeftButtonDown;
}
}
// ##############################################################################################################################
// Overrides
// ##############################################################################################################################
public override void OnApplyTemplate()
{
_PartDragMove = GetTemplateChild("PART_DragMove") as Rectangle;
if (_PartDragMove != null)
{
_PartDragMove.PreviewMouseLeftButtonDown += PartDragMove_OnPreviewMouseLeftButtonDown;
}
base.OnApplyTemplate();
}
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
if (IsMouseDownOnDrag)
{
_AnchorPoint = PointToScreen(e.GetPosition(this));
_IsDragging = true;
CaptureMouse();
e.Handled = true;
}
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (_IsDragging)
{
Point currentPoint = PointToScreen(e.GetPosition(this));
double newLeftPosition = Left + currentPoint.X - _AnchorPoint.X;
double newTopPosition = Top + currentPoint.Y - _AnchorPoint.Y;
//control area
if (newLeftPosition < _DragMoveArea.X)
newLeftPosition = _DragMoveArea.X;
if (newTopPosition < _DragMoveArea.Y)
newTopPosition = _DragMoveArea.Y;
if(newLeftPosition + ActualWidth > _DragMoveArea.X + _DragMoveArea.Width)
newLeftPosition = _DragMoveArea.X + _DragMoveArea.Width - ActualWidth;
if (newTopPosition + ActualHeight > _DragMoveArea.Y + _DragMoveArea.Height)
newTopPosition = _DragMoveArea.Y + _DragMoveArea.Height - ActualHeight;
Left = newLeftPosition;
Top = newTopPosition;
_AnchorPoint = currentPoint;
}
}
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
{
IsMouseDownOnDrag = false;
if (_IsDragging)
{
_IsDragging = false;
e.Handled = true;
ReleaseMouseCapture();
}
}
// ##############################################################################################################################
// Events
// ##############################################################################################################################
private void PartDragMove_OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs mouseButtonEventArgs)
{
IsMouseDownOnDrag = true;
}
// ##############################################################################################################################
// Public Methods
// ##############################################################################################################################
public void SetDragMoveArea(Rect area)
{
_DragMoveArea = area;
}
所以现在我只是在我的SetDragMoveArea()
内ChildWindow
已锁定时才调用WindowContainer
。
我正在使用以下代码提取该区域的信息
WorkingArea = WindowContainer.TransformToAncestor(System.Windows.Application.Current.MainWindow).TransformBounds(new Rect(new Point(0, 0), WindowContainer.RenderSize));
默认情况下,它是否锁定在Screen
内(请参阅_OnLoaded
)。
答案 0 :(得分:1)
我找到了适合你的解决方案。如果要自定义移动,则无法使用DragMove
方法。相反,您必须自己实现此功能,覆盖以下三个功能:OnMouseLeftButtonDown
,OnMouseMove
和OnMouseLeftButtonUp
。
我已经实现了类似的东西:
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
anchorPoint = e.GetPosition(this);
inDrag = true;
CaptureMouse();
e.Handled = true;
}
anchorPoint
是我用于Binging窗口位置的点,inDrag
是私有布尔值,CaptureMouse
是UIElement
方法。
然后:
protected override void OnMouseMove(MouseEventArgs e)
{
if (inDrag)
{
Point currentPoint = e.GetPosition(this);
this.Left = this.Left + currentPoint.X - anchorPoint.X;
/*this.Top = this.Top + currentPoint.Y - anchorPoint.Y*/; // this is not changing in your case
anchorPoint = currentPoint;
}
}
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
{
if (inDrag)
{
ReleaseMouseCapture();
inDrag = false;
e.Handled = true;
}
}
其中ReleaseMouseCapture
是UIElement
方法。
我认为它应该对你有帮助。