编程 & 生活 -- 西西吹雪

开心工作,快乐生活 (原创文章,转载请注明出处)

导航

一种有效的向导实现方式

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

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


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


    
public class WizardFacade
    
{
        
private System.Windows.Forms.Control m_ParentControl;
        
private System.Windows.Forms.Control m_CurrentControl;

        
public WizardFacade(Control parentControl)
        
{
            m_ParentControl 
=parentControl;

            EntranceControl ctl 
= new EntranceControl()
            SetCurrentControl(selctl);
        }


        
/// <summary>
        
/// 将某一个控件设为当前控件,并显示出来
        
/// </summary>
        
/// <param name="subControl"></param>

        private void SetCurrentControl(Control subControl)
        
{            
            
if (m_CurrentControl != null)
            
{
                (subControl 
as IWizardStep).Chart = (m_CurrentControl as IWizardStep).Chart;
                (subControl 
as IWizardStep).LastStepControl = m_CurrentControl;
            }


            subControl.Parent 
= m_ParentControl;
            subControl.Location 
= new System.Drawing.Point(0,0);
            subControl.BringToFront();
            subControl.Visible 
= true;

            m_CurrentControl 
= subControl;
        }


        
/// <summary>
        
/// 执行下一步
        
/// </summary>

        public void GoNext()
        
{
            (m_CurrentControl 
as IWizardStep).BeforeGoNext();
            
if ((m_CurrentControl as IWizardStep).NextStepControl != null)
            
{    
                SetCurrentControl((m_CurrentControl 
as IWizardStep).NextStepControl);
            }

        }


        
/// <summary>
        
/// 执行上一步
        
/// </summary>

        public void GoLast()
        
{
            
if ((m_CurrentControl as IWizardStep).LastStepControl != null)
                SetCurrentControl((m_CurrentControl 
as IWizardStep).LastStepControl);
        }


        
/// <summary>
        
/// 获取当前正在显示的控件
        
/// </summary>
        
/// <returns></returns>

        public Control CurrentStepControl
        
{
            
get
            
{
                
return m_CurrentControl;
            }

        }

        

    }

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


      

posted on 2006-07-04 15:06  西西吹雪  阅读(739)  评论(0编辑  收藏  举报