1

这是一个有点不同的问题,或者可能是一个简单的问题。但我现在有这个问题。

我有三种形式loginFormmainFormsubForm
在我loginForm的帐户中,我有两个帐户,一个用于mainForm访问,另一个用于subForm访问。可以同时访问
,但只能访问。通过我们可以创建多个实例(是单实例)。mainFormAccessAccountmainFormsubFormsubFormAccessAccountsubForm
mainFormsubFormmainForm

现在我的问题是:我想及其实例(由创建的实例subForm_Closed的事件函数。subFormmainForm

我使用下面的代码subFormsubForm.cs中创建实例

private mainForm MainForm;
    internal void RegisterParent(mainForm form)
    {
        this.MainForm = form;
    }

并在mainForm.cs中创建实例subForm,我使用了以下代码:

subForm newSubForm = new subForm();
newSubForm.Show();
newSubForm.RegisterParent(this);

我该如何解决这个问题?
(我不确定它们是否被称为实例,因为我是 Dot net noob)

提前致谢。

4

4 回答 4

2

如果我正确理解您的问题,您需要两个不同的处理程序来处理子表单的关闭事件。

  1. 通过 subFormAccessAccount 创建的 SubForm 关闭事件的一个处理程序
  2. 通过 MainForm 创建的 SubForm 关闭事件的另一个处理程序

正如您所怀疑的,这确实是一个简单的问题,既然您提到您是一个 .net 菜鸟,我将尝试详细解释。

如果我没记错的话,您subForm_Closed使用 Visual Studio 设计器表面生成了事件处理程序。这似乎是你困惑的原因。

Visual Studio 设计器如何生成事件处理程序:

如果您打开 SubForm.cs,请注意其构造函数的定义。会是这样的

public SubForm()
{
     InitializeComponent();
     //May be some other code as well
}

InitializeComponent方法在 SubForm.designer.cs file() 中有描述(在解决方案资源管理器中展开 SubForm.cs 即可看到)。

方法中的一行InitializeComponent将是这样的

this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.SubForm_Closed);

因此,只要您通过 subFormAccessAccount 或 MainForm 创建一个子表单“实例”(这里我的意思是真实的对象实例,而不是您在问题中提到的充其量是子表单的意义上),它就会附加您的 SubForm_Closed 事件FormClosed 事件的处理程序。

如何获得所需的行为?

如果要处理 SubForm.cs 中的关闭事件,可以执行以下操作

internal void RegisterParent(mainForm form)
{
    this.MainForm = form;
    this.FormClosed -= SubForm_Closed; //Unhook previous handler
    this.FormClosed += SubFormAsChild_Closed; //hook new handler
}

如果要处理 MainForm.cs 中的关闭事件,可以这样做

internal void RegisterParent(mainForm form)
{
    this.MainForm = form;
    this.FormClosed -= SubForm_Closed;
}

//in MainForm.cs
newSubForm.RegisterParent(this);
newSubForm.FormClosed += newSubForm_Closed;
于 2012-10-05T11:54:20.250 回答
1

几种方法向 SubForm 添加另一个构造函数

例如

public SubForm(Boolean argCreatedByMainForm) : this()
{
// save argument in private member variable for use in OnCloseQuery
}

然后使用

subForm newSubForm = new subForm(true);
newSubForm.Show();
newSubForm.RegisterParent(this); 

这不是我要走的路,因为让一种形式知道另一种形式,往往会变成维护的噩梦,但你需要在你的编程盒中使用更多工具来实现更好的解决方案。例如,一个管理表单之间交互的类,然后将它们抽象为接口,最后但并非最不重要的是注入行为。

看到你正在学习,让构造函数工作,当你学习技术时,你可以进步到愚蠢的聪明

于 2012-10-05T13:02:53.833 回答
0
subForm newSubForm = new subForm();
newSubForm.Show();
newSubForm.RegisterParent(this);
newSubForm.Close += (s, e) =>
{
   // Close event will be fired for this instance only.
};
于 2012-10-05T11:30:08.683 回答
0

我建议您使用其他结构的主窗体 - 子窗体引用。

您的 Subform 派生自 System.Windows.Forms.Form,System.Windows.Forms.Control 派生自 System.Windows.Forms.Control,它实际上已经有一个属性来存储父控件:因此您应该将对主窗体的引用存储在那里。

另一件事是你应该实现一个静态方法来在你的主窗体中创建子窗体,它会调用单个实例引用的私有方法来创建真正的子窗体 - 我假设你是单例模式。

所以代码看起来像这样

public class MainForm : System.Windows.Forms.Form 
{
  // used to hold references to subforms note: not static
  private List<SubForm> mySubForms;

  // singelton implementation
  private static MainForm theInstance = null;      
  private MainForm()
  {
     mySubForms = new List<SubForm>();
  }
  public static MainForm GET_INSTANCE()
  {
     if (MainForm.theInstance == null)
     {
       MainForm.theInstance = new MainForm();
     }
     return MainForm.theInstance;
  }

  // creates subforms and the references right not:static method as singelton 
  //pattern is used
  public static SubForm CREATE_SUBFORM()
  {
     SubForm newSub = new SubForm();
     newSub.Parent = theInstance;
     theInstance.mySubForms.Add(newSub);
     return newSub;
  }
}

如果代码有一些打字错误,请道歉......我现在没有 IDE。显然我没有实现单格模式线程安全......这将是出于演示目的的边缘。

编辑:更好的做法是让表单通过使用 evetns 进行通信。如果您打算拥有一个多线程应用程序,这将是最好的方法。但是你需要先进的 .Net 技能才能做到这一点 - imo。

于 2012-10-05T11:57:11.513 回答