我是c#的新手。我的申请有两种表格,比如Form1
和Form2
。每当Form2
移动时,Form1
都应执行操作。
传统方法:
我知道我可以将Form1作为Form2的成员,并手动调用我需要做的任何方法。但我不喜欢这种方法。我希望这两种形式都是独立的。我希望它具有足够的可扩展性,以便为Form2的移动活动添加监视,例如调整大小,关闭等等。
自定义活动提升:
我遇到了关于提升事件的MSDN article,但很难理解并且似乎是为了创建自定义事件并在必要时发送事件。这看起来比第一种方法好一些,但在发生与Form2
的交互时我应该发送自定义事件的方式类似。我的要求更多地基于默认事件,如位置已更改,已关闭,已调整大小等。
有什么方法可以订阅 Form1
来接收Form2
的默认事件?
我猜是一个非常简单的要求。请详细说明一下。
答案 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。该模式确保在其他人获得事件之前,只要属性发生更改,就会通知派生类。