3

我看过一些关于此的帖子,但它们不一定准确回答我的问题。

我有一个父窗口,在它的LocationChanged事件中,它会抓取一个子窗口并以“捕捉”的方式将它与它一起移动。我想找到一个事件并在子表单上设置一个布尔值"if the user has manually moved me, I will not re-attach to the parent."

有没有办法检测用户是否移动了子窗口,而不是我的父窗口移动它?

我希望这是有道理的。

4

1 回答 1

6

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

在您的子窗口中创建一个事件,通知侦听器将子窗口与其父窗口解除关联(分离):

public event EventHandler<EventArgs> DetachOwner;

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

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

将此添加到您的子窗口:

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;
}
于 2013-05-08T05:56:28.133 回答