当另一个表单移动或关闭时,是否可以在表单中获取通知或事件

时间:2018-02-01 06:42:48

标签: c# .net forms winforms events

我是c#的新手。我的申请有两种表格,比如Form1Form2。每当Form2移动时,Form1都应执行操作。

传统方法:

我知道我可以将Form1作为Form2的成员,并手动调用我需要做的任何方法。但我不喜欢这种方法。我希望这两种形式都是独立的。我希望它具有足够的可扩展性,以便为Form2的移动活动添加监视,例如调整大小,关闭等等。

自定义活动提升:

我遇到了关于提升事件的MSDN article,但很难理解并且似乎是为了创建自定义事件并在必要时发送事件。这看起来比第一种方法好一些,但在发生与Form2的交互时我应该发送自定义事件的方式类似。我的要求更多地基于默认事件,如位置已更改,已关闭,已调整大小等。

有什么方法可以订阅 Form1来接收Form2的默认事件?

我猜是一个非常简单的要求。请详细说明一下。

2 个答案:

答案 0 :(得分:1)

您的Form1需要Form2的引用,然后它可以收听它喜欢的任何事件 - 例如在Form1内:

public void RegisterForm2(Form2 form2)
{
    form2.SizeChanged += (s, e) => { /* handle resize */ };
    // same for other events
}

然后在您创建表单的应用程序外部:

var form1 = new Form1();
var form2 = new Form2();
form1.RegisterForm2(form2);

答案 1 :(得分:1)

每当Form2移动时,它都会引发事件Control.Move。您可能还对LocationChanged和Resize事件感兴趣。

不知何故,Form1需要知道Form2的存在。为了整洁处理,Form1还需要知道Form2何时关闭。因此,让我们编写当有人创建Form2时应该调用的函数:

在Form2中:

void DependantFormCreated(Form otherForm)
{
    // this form needs to be notified whenever otherForm moves
    otherForm.Move += OtherFormMoved;
    // now whenever otherFormMoves, my function DependantFormMoved is called

    // this form also needs to be notified when otherForm closes:
    otherForm.Closed += OtherFormClosed;
}

private void OtherFormMoved(object sender, eventArgs e)
{
     Control otherForm = (Control)sender;
     Point location = otherForm.Location;
     ProcessOtherFormPosition(location);
}

private void OtherFormClosed(object sender, eventargs e)
{
    // other form does not exist anymore
    ProcessOtherFormClosed()'
}

提示:在视觉工作室中,当您在事件后写入+ =时,请按<TAB>两次。这将为您创建eventhandler函数。如果会有类似上面的签名。

如果您对其他课程的活动不再感兴趣,只需使用 - =

即可
this.OtherForm -= OtherFormMoved;

因此,您需要记住您订阅事件的对象。

如果您创建了一个课程,并且想要通知“可能感兴趣的每个人”您班级中的某些内容发生了变化或发生了变化,那么只需给您的课程一个事件并在项目发生变化时将其提升:

public MyPropertyType MyProperty {get; private set;}

public event EventHandler MyPropertyChanged;

protected virtual void OnMyPropertyChanged ()
{
    // note: needs availability of null coalesence operator:
    this.MyPropertyChanged?.Invoke(this, EventArgs.Empty);
}

private SomeOtherFunction()
{
    this.MyProperty = ...
    this.OnMyPropertyChanged();
}

通常你会看到以下模式。这样您就可以确定每次MyProperty更改时,都会引发事件:

private MyPropertyType myProperty = ...;
public MyPropertyType MyProperty
{
    get {return myProperty; }
    set
    {
         if (value != this.myProperty)
         {   // value changed: update + event
             this.myProperty = value;
             this.OnMyPropertyChanged();
         }
    }
}

班级用户应该执行以下操作:

void Initialize()
{
    OtherClass otherObject = ...
    otherObject.MyPropertyChanged += this.ProcessMyPropertyChanged;
}

private void ProcessMyPropertyChanged(object sender, EventArgs e)
{
     OtherClass otherObject = (OtherClass)sender;
     MyPropertyType value = otherObject.MyProperty;
     ProcessPropertyChange(value);
}

仅在您不再需要这些活动时才需要:

OtherClass otherObject = ...
otherObject.MyPropertyChanged -= ProcessMyPropertyChanged();

}

派生类不应订阅该事件,但应重写OnMyPropertyChanged。该模式确保在其他人获得事件之前,只要属性发生更改,就会通知派生类。