在运行时确定表单的标识(类型信息)

时间:2015-07-13 15:13:17

标签: c# casting runtime

假设我有一个执行一些耗时步骤的公共类(例如,将内容保存到USB)。我希望能够从多个表单中调用该代码,并在步骤完成时收到反馈。普通班级如何知道向谁发送反馈?下面的代码描述了这种情况:

// ### Common class frmCommon ###
// Parent form (when feedback on some slow operation is required)
private static Form m_frmParent = null;

// ...
public static void SetParentForm(Form frmParent)
{
    // When some time consuming process takes place (such as saving to USB), setting the
    // parent form allows feedback to be given to the user (eg. as a progress bar)
    m_frmParent = frmParent;
}

public static void DoSomething()
{
    for (int nStep = 0; nStep < 100; nStep++)
    {
        // Tell the parent form how many product sets (groups of 20) there are to read
        if (m_frmParent != null)
        {
            // How to decide whether to call form 1 or form 2?
            ((frmForm1)m_frmParent).SendFeedback(nStep);
            ((frmForm2)m_frmParent).SendFeedback(nStep);
        }

        // Perform the time-consuming step...
        SlowStep(nStep);
    }
}

// ### FORM 1 frmForm1 ###
private void SomeEventForm1(int nStep)
{
    frmCommon.SetParentForm(this);
    frmCommon.DoSomething();
    frmCommon.SetParentForm(null);
}

public void SendFeedback(int nStep)
{
    // Do something like update a progress bar on form 1
    Application.DoEvents();
}

// ### FORM 2 frmForm2 ###
private void SomeEventForm2(int nStep)
{
    frmCommon.SetParentForm(this);
    frmCommon.DoSomething();
    frmCommon.SetParentForm(null);
}

public void SendFeedback(int nStep)
{
    // Do something like update a progress bar on form 2
    Application.DoEvents();
}

如果能有所作为,则瞄准.NET 2.0。

3 个答案:

答案 0 :(得分:1)

调用代码必须为该类提供委托。当类完成耗时的过程时,它将调用该委托来通知调用代码它已完成。请查看here以获取有关如何执行此操作的详细教程。

答案 1 :(得分:1)

1 - 如果SendFeedback是您在两种表单中实现的功能,并且他们也会这样做,请考虑在static扩展static class方法 Form

public static class FormExtender
{
    public static void SendFeedback(this Form frm, int nStep)
   {
       //do what must be done
       //you can call this anyhere using, for instance: m_frmParent.SendFeedback(nStep)
       //when you call it like that, m_frmParent will be given to this function as the argument frm
   }

}

2 - 但如果两种形式的方法不同,我建议你创建一个界面:

interface IFormWithFeedback
{
    void SendFeedback(int nStep);
}

然后form1和form2应该实现这一点(只需在声明表单的地方添加, IFormWithFeedBack):

public class frmForm1 : Form, IFormWithFeedback     
public class frmForm2 : Form, IFormWithFeedback

此类中的父表单应为IFormWithFeedback而不是表单:

 private static IFormWithFeedback m_frmParent = null;

两个选项(扩展方法或接口)都允许您从m_frmParent调用SendFeedback direclty而不进行强制转换。

答案 2 :(得分:1)

我宁愿使用事件

public class SlowProcess {
  ...
  // Simplest, not thread safe
  public static event EventHandler<int> StepChanged;

  public static void DoSomething() {
    for (int nStep = 0; nStep < 100; nStep++) {
      if (null != StepChanged)
        StepChanged(null, nStep);

      SlowStep(nStep);
    } 
  }
}

...

public partial class MyEventForm: Form {
  ...    
  private void onStepChange(Object sender, int nStep) {
    //TODO: update form here after receiving a feedback 
  }

  private void TraceSlowProcess() {
    // feedback is required 
    SlowProcess.StepChanged += onStepChange;

    try {
      SlowProcess.DoSomething(); 
    }
    finally {
      // No need of feedback
      SlowProcess.StepChanged -= onStepChange;
    }
  }
}