在运行时确定表单的身份(类型信息)
Determine form's identity (type information) at runtime
假设我有一个常见的 class 执行一些耗时的步骤(例如,将内容保存到 USB)。我希望能够从多种形式调用该代码,并在完成一个步骤时收到反馈。普通 class 如何知道向谁发送反馈?下面的代码描述了这种情况:
// ### 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,如果有影响的话。
调用代码必须向 class 提供委托。当 class 完成耗时过程后,它将调用该委托以通知调用代码它已完成。查看 here 以获得有关如何执行此操作的良好教程。
1 - 如果 SendFeedback
是您在两种形式中实现的函数,并且它们的作用相同,请考虑在 static class
到 [=31= 中创建单个 static
方法]扩展 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
并且您在 class 中的父表单应该是 IFormWithFeedback
而不是表单:
private static IFormWithFeedback m_frmParent = null;
这两个选项(扩展方法或接口)都允许您直接从 m_frmParent 调用 SendFeedback
而无需转换它。
我宁愿使用 事件:
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;
}
}
}
假设我有一个常见的 class 执行一些耗时的步骤(例如,将内容保存到 USB)。我希望能够从多种形式调用该代码,并在完成一个步骤时收到反馈。普通 class 如何知道向谁发送反馈?下面的代码描述了这种情况:
// ### 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,如果有影响的话。
调用代码必须向 class 提供委托。当 class 完成耗时过程后,它将调用该委托以通知调用代码它已完成。查看 here 以获得有关如何执行此操作的良好教程。
1 - 如果 SendFeedback
是您在两种形式中实现的函数,并且它们的作用相同,请考虑在 static class
到 [=31= 中创建单个 static
方法]扩展 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
并且您在 class 中的父表单应该是 IFormWithFeedback
而不是表单:
private static IFormWithFeedback m_frmParent = null;
这两个选项(扩展方法或接口)都允许您直接从 m_frmParent 调用 SendFeedback
而无需转换它。
我宁愿使用 事件:
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;
}
}
}