Winform 窗口加载实例(三)-----功能菜单

本文探讨如何在Winform的MDI应用程序中实现类似Excel的功能菜单,包括父窗口调用子窗口功能、子窗口功能多样化以及子窗口控制父窗口控件。通过虚函数、重写和ActiveMdiChild属性,实现MDI子窗口间的交互,并提供了一个使用示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      打开Excel,我们发现Excel的每个Sheet里面并没有任何的功能操作按钮或菜单,但是我们仍然能对每个sheet进行各种操作,这些操作都可以 由上面的功能菜单来实现。对于MDI形式的界面,从某种程度上来看,就很类似一个Excel Application,那能不能实现像Excel Application那样的功能操作呢?

      要实现那样的功能操作,有几个问题需要解决:

      (1)MDI父界面能调用到MDI子界面的功能

      (2)MDI子界面对通过一个功能,能不同实现

      (3)MDI子窗口可以实现对父窗口的控件控制(扩展功能)

     界面实现的形式如下:

 

      上面是一般菜单,下面是通用功能按钮。每个按钮都可以实现子窗口的功能,通俗的说就是“不用你来调用我,只需我来调用你”(比较类似于观察者模式)。当然实现这中设计,每个子界面的功能要有很大的相似性才比较好,否则最好不要这样设计。

       我们知道,在.net的方法调用中,如果是非静态的方法,需要先实例化类的对象,然后才能调用类的方法,如果是静态方法,也是需要知道具体的类才能调用其 方法。如果在MDI父窗口的功能要调用MDI子窗口的功能,是否需要实例化每个MDI子窗口的对象才能调用其方法呢?在.net的继承中,子类可以强制转 换成父类,如果每个子窗口都继承与某个父窗口,这样MDI父窗口调用MDI子窗口的功能的时候,只要实例化父窗口然后调用其方法就行了。通过虚函数和重写可以实现子类的多样化。

      首先我们来定义一个父窗口,用于继承,比如命名为frmBase,然后定义其功能函数:

      public partial class frmBase: Form

     {

         public virtual void PicPrintView()
        {

             MessageBox.Show("打印");
        }

       public virtual void UpdateStatus(int iStatus)
        {

        }

        public virtual void PicSave()
        {

        }

      }

      定义个子窗口,都继承自frmBase,实现对应的功能函数:

    public partial class frmCustomer: frmBase

     {

       
       public override void UpdateStatus(int iStatus)
        {
               MessageBox.Show(iStatus.ToString());
        }

        public override void PicSave()
        {
             MessageBox.Show("保存");
        }

      }

        最后要实现的就是在MDI父窗口调用对应的功能。要调用MDI子窗口的功能能,我们首先要知道的是调用的是那个窗口的,对应MDI的形式,可以通过this.ActiveMdiChild获取当前活动的窗口,所以在MDI父窗口的事件上:

         private void picPrint_Click(object sender, EventArgs e)
        {
            if (this.ActiveMdiChild != null)
            {
                frmBase frm = (frmBase)this.ActiveMdiChild;
                frm.PicPrint();
            }
        }

         这样就实现了对frmCustomer中打印功能的实现。如果每个子窗体的功能都一样,我们只需要在继承的父窗口实现功能,子窗口不重写对应的方法就行了,扩展开来,如果子窗口没有这个功能,不重写对应的方法就可以了(PicPrintView)。

         写到这里,基本的功能已经实现了。其实主要就是使用了虚函数和重写,还有一个MDI窗口特有的属性ActiveMdiChild。我这里是通过方法来实现的,当然也可以通过委托来实现,还可以通过委托+事件来实现。

         对于第三个功能“MDI子窗口可以实现对父窗口的控件控制”,主要是在子窗口不实现功能的时候使用。可能在MDI父窗体有多个按钮实现子界面的功能,但是某个子界面只需要实现其中的几个功能,虽然通过不重写方法就不实现了其中的功能,但是在可视化程序设计下,没有实现功能的控件(按钮,菜单等)最好不显示或者不可操作。

        在MDI父窗口中,将其控件装换成其属性:

           public Button BtnSave
        {
            get { return this.btnSave; }
        }

        public Button BtnNew
        {
            get { return this.btnSave; }
        }

        在继承父窗口,实现控制MDI父窗口控件的方法:

            frmMain frm = null;

        private void frmBase_ParentChanged(object sender, EventArgs e)
        {
            if (this.MdiParent != null)
                frm = (frmMain)this.MdiParent;
        }

        public  void ShowButton(bool bSave, bool bNew)
        {
            frm.BtnNew.Visible = bNew;
            frm.BtnSave.Visible = bSave;
        }

        在继承子窗口,实现具体控制,即调用父类中的方法:

        private void frmCustomer_Load(object sender, EventArgs e)
        {
            ShowButton(true, false);

          }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值