• 一种有效的向导实现方式


      在软件开发中,对于需要比较复杂,需要多步完成的操作,我们一般采用向导的方式来提供用户界面。向导设计本身并不困难,但如果要做到通用性强,模块间尽量低耦合,我们还是得动一下脑筋的。下面介绍一下我的实现方式。
        典型的向导界面,主界面上一般包含两个区域,一是选项区域,二是按钮区域,包含上一步,下一步,取消等按钮。向导执行后,每一步该做什么,如果通过条件判断来进行,显然会非常麻烦。理想的做法是,上一步的代码为:
       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对象实例,然后调用相应的方法就可以了。
      
      实践证明,上述思路简单,清晰,实用,稍作扩展,可以实现更强大的功能,或者定制你业务中所需要的功能。
       


          

  • 相关阅读:
    图解ArrayList源码
    HashMap相关
    1. 两数之和
    判定字符是否唯一
    反射相关
    自定义注解
    TreeMap相关
    判定是否互为字符重排
    2. 两数相加
    线程基础
  • 原文地址:https://www.cnblogs.com/watsonyin/p/442255.html
Copyright © 2020-2023  润新知