一种有效的向导实现方式

  在软件开发中,对于需要比较复杂,需要多步完成的操作,我们一般采用向导的方式来提供用户界面。向导设计本身并不困难,但如果要做到通用性强,模块间尽量低耦合,我们还是得动一下脑筋的。下面介绍一下我的实现方式。
    典型的向导界面,主界面上一般包含两个区域,一是选项区域,二是按钮区域,包含上一步,下一步,取消等按钮。向导执行后,每一步该做什么,如果通过条件判断来进行,显然会非常麻烦。理想的做法是,上一步的代码为:
   GoLast(); 
       下一步的代码为:
           GoNext();
         那怎么做到这一点呢?
        
        首先概念上,我们明确,向导由若干步组成,每一步可以由一个UserControl来表示,执行到该步时,只是创建一个该控件的实例,并显示在向导主界面的选项区域而已,这一点是不难做到的。那么现在问题的关键就是将这些步串联起来,能够做到自动的运行。这个任务可以分散到每一步的控件中去,也就是说,每一步应当知道它的上一步是什么,下一步它该做什么,这一点在逻辑上应当是没有疑虑的。所以,我设计了一个接口IWizardStep,代码如下:

     public   interface  IWizardStep
    {
        Control NextStepControl
        {
            
get ;
        }
        Control LastStepControl
        {
            
get ; set ;
        }        
        
void  BeforeGoNext();
    }


         其中,   NextStepControl表示下一步的控件,如果是最后一步,则应为null,;LastStepControl表示上一步控件,如果是第一步,则该值应null 。BeforeGoNext用于在执行下一步时,做一些选项的应用等预处理工作。每一步的控件只要实现了该接口,向导中的各个步骤就有次序的连接在一起了。
        有了上面的这些工作,我们只需要再设计一个用来供主界面调用的外观类,向导就可以很好的运行了。

None.gif
None.gif    
public   class  WizardFacade
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif        
private System.Windows.Forms.Control m_ParentControl;
InBlock.gif        
private System.Windows.Forms.Control m_CurrentControl;
InBlock.gif
InBlock.gif        
public WizardFacade(Control parentControl)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            m_ParentControl 
=parentControl;
InBlock.gif
InBlock.gif            EntranceControl ctl 
= new EntranceControl()
InBlock.gif            SetCurrentControl(selctl);
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 将某一个控件设为当前控件,并显示出来
InBlock.gif        
/// </summary>
ExpandedSubBlockEnd.gif        
/// <param name="subControl"></param>

InBlock.gif        private void SetCurrentControl(Control subControl)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{            
InBlock.gif            
if (m_CurrentControl != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                (subControl 
as IWizardStep).Chart = (m_CurrentControl as IWizardStep).Chart;
InBlock.gif                (subControl 
as IWizardStep).LastStepControl = m_CurrentControl;
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            subControl.Parent 
= m_ParentControl;
InBlock.gif            subControl.Location 
= new System.Drawing.Point(0,0);
InBlock.gif            subControl.BringToFront();
InBlock.gif            subControl.Visible 
= true;
InBlock.gif
InBlock.gif            m_CurrentControl 
= subControl;
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 执行下一步
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        public void GoNext()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            (m_CurrentControl 
as IWizardStep).BeforeGoNext();
InBlock.gif            
if ((m_CurrentControl as IWizardStep).NextStepControl != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{    
InBlock.gif                SetCurrentControl((m_CurrentControl 
as IWizardStep).NextStepControl);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 执行上一步
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        public void GoLast()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if ((m_CurrentControl as IWizardStep).LastStepControl != null)
InBlock.gif                SetCurrentControl((m_CurrentControl 
as IWizardStep).LastStepControl);
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 获取当前正在显示的控件
InBlock.gif        
/// </summary>
ExpandedSubBlockEnd.gif        
/// <returns></returns>

InBlock.gif        public Control CurrentStepControl
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return m_CurrentControl;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif
ExpandedBlockEnd.gif    }

        需要注意的是,在构造函数中,有一个EntranceControl的变量,是入口控件,也就是向导的第一步要显示的控件。在外观类中明确该控件,在职现分配上应当也是符合逻辑的。
  
  做完了这些,我们的向导主界面就非常简单了,只需要创建一个WizardFacade对象实例,然后调用相应的方法就可以了。
  
  实践证明,上述思路简单,清晰,实用,稍作扩展,可以实现更强大的功能,或者定制你业务中所需要的功能。
   


      

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值