检测用户是否移动了WPF中的窗口

本文关键字:窗口 WPF 用户 是否 移动 检测 | 更新日期: 2023-09-27 18:12:39

我看过一些关于这个的帖子,但是他们不一定完全回答我的问题。

我有一个父窗口,在它的LocationChanged事件上,它将抓取一个子窗口并以"抓拍"的方式移动它。我想找到一个事件并在子窗体上设置一个布尔值比如"if the user has manually moved me, I will not re-attach to the parent."

是否有一种方法来检测是否用户移动了子窗口,而不是我的父窗口移动它?

检测用户是否移动了WPF中的窗口

假设您正在使用子窗口的Owner属性将父窗口关联到子窗口,我会使用基于事件的方法。

在子窗口中创建一个事件,通知侦听器将子窗口从其父窗口中分离(分离):

public event EventHandler<EventArgs> DetachOwner;

接下来需要确定何时引发此事件。为此,我们将在子窗口中使用三个事件:Activated, DeactivatedLocationChanged

LocationChanged将告诉我们子窗口何时移动,但我们需要过滤掉子窗口移动的情况,因为它跟随父窗口。要做到这一点,我们需要知道子窗口是否在移动并且它有焦点。为了跟踪子窗口的焦点状态,创建一个名为HasFocus的bool字段,并将HasFocus在窗口的Activated事件处理程序中设置为true,在窗口的Deactivated处理程序中设置为false。

添加到子窗口:

private void Window_LocationChanged(object sender, EventArgs e) {
    if (HasFocus) {
        if (DetachChild != null) {
            DetachChild(this, EventArgs.Empty);
        }
    }
}
bool HasFocus;
private void Window_Activated(object sender, EventArgs e) {
    HasFocus = true;
}
private void Window_Deactivated(object sender, EventArgs e) {
    HasFocus = false;
}

在父窗口中,当你实例化子窗口时,你将订阅子窗口的DetachOwner事件:

_child = new Child();
_child.Owner = this;
// Subscribe to the DetachOwner event.
_child.DetachChild += Child_DetachOwner;

这个DetachOwner处理程序简单地将子窗口的Owner属性设置为null:

void Child_DetachOwner(object sender, EventArgs e) {
    ((Child)sender).Owner = null;
}

您可以扩展此方法,通过在子窗口中创建一个类似的AttachOwner事件,并在父窗口中使用处理程序,将子窗口重新附加到其父窗口:

void Child_AttachOwner(object sender, EventArgs e) {
    ((Child)sender).Owner = this;
}