2019-8-15C#MDI窗體實現多窗口效果


C#MDI窗體實現多窗口效果  
Visual C#是微軟公司推出的下一代主流程序開發語言,他也是一種功能十分強大的程
序設計語言,正在受到越來越多的編程人員的喜歡。在Visual C#中,提供了為實現MDI程序設計的很多功能。本文就是通過一個具體的例子來詳細的介紹在Visual C#中的MDI編程。   
  一程序設計及運行的環境:
  (1)視窗2000服務器版
  (2).Net FrameWork SDK Beta 2版
  二程序設計的思路、主要步驟和實現方法:
  MDI編程主要就是要在主窗體中能夠新建一個MDI窗體,並且能夠對主窗體中的所有MDI窗體實現層疊、水平平鋪和垂直平鋪。雖然這些操作比較基本,但卻是程序設計中的要點和重點。本文就按照上述功能的順序來一一介紹。
  (1)首先要設定主窗體是一個MDI窗體的容器,因為只有如此才能夠在此主窗體上面添加MDI窗體,從而實現對MDI編程,具體實現語句如下:
  
public Form1()
 {
            InitializeComponent();
            this.IsMdiContainer = true;
 }

我是直接把this.IsMdiContainer = true ;寫在窗體的構造函數中,你也可以寫的form_load函數中。


  (2)在主窗體上面新建一個MDI窗體。在程序中,新建一個MDI窗體的命令是通過一個菜單的事件來實現的。在處理新建一個MDI窗體事件中,關鍵是要設定此MDI窗體的父窗體。其實MDI窗體和別的窗體沒有什么不同,不同點就在MDI窗體有上一級窗體,即父窗體,而其他窗體是沒有的,具體實現語句如下:
復制代碼
private void New_Click (  object sender , EventArgs e )//這是一個菜單的事件
{
  Form frmTemp = new Form ( ) ;
  //新建一個窗體
  frmTemp.MdiParent = this ;
  //定義此窗體的父窗體,從而此窗體成為一個MDI窗體
  frmTemp.Text = "窗體0" + FormCount.ToString ( ) ;
  //設定MDI窗體的標題
  FormCount++ ;
  frmTemp.Show ( ) ;
  //把此MDI窗體顯示出來
}
復制代碼


(3)實現對MDI窗體的層疊:
  對於在主窗體中實現對MDI窗體的層疊操作,在主程序中,是通過一個方法來實現的,這個方法就是LayoutMdi,他所帶的參數是MdiLayout.Cascade,具體實現語句如下:

private void Cascade_Click ( object sender , EventArgs e )  //實現對主窗體中的MDI窗體的層疊操作
{
  this.LayoutMdi ( MdiLayout.Cascade ) ;
}


實現操作后具體如下圖:

 
圖01:在主窗體中實現對MDI窗體的層疊操作,點擊小圖放大

  (4)實現對MDI窗體的水平平鋪:
  要在主窗體實現MDI窗體水平平鋪,也是通過LayoutMdi方法,此時所帶的參數是MdiLayout.TileHorizontal,具體實現語句如下:
this.LayoutMdi ( MdiLayout.TileHorizontal ) ;
 
實現操作后具體如下圖:

圖02:在主窗體中實現對MDI窗體的水平平鋪操作,點擊小圖放大

  (5)實現對MDI窗體的垂直平鋪:
  要在主窗體實現MDI窗體垂直平鋪,也是通過LayoutMdi方法,此時所帶的參數是MdiLayout.TileVertical,具體實現語句如下:
this.LayoutMdi ( MdiLayout.TileVertical ) ;//實現對主窗體中的MDI窗體的垂直平鋪操作
 
實現操作后具體如下圖:
圖03:在主窗體中實現對MDI窗體的垂直平鋪操作,點擊小圖放大

  (6)在有些MDI程序,當新建一個MDI窗體以后,往往會在某些菜單項的下面生產一個以此MDI窗體的名稱為名稱的子菜單項。在其他語言中要實現這種功能,可能就要在某些主菜單項下動態的加入子菜單了。但是在Visual C#中實現此種功能,就顯得比較簡單的,只有在要加入的主菜單項下加入下面一句程序就可以了:
  WindowMenu.MdiList = true ;本程序中,是在"窗口"主菜單項下面加入MDI窗體的子菜單項的。加入此語句后,程序運行界面具體如下圖:
圖04:在主窗體中實現在新建一個MDI窗體后會在此主菜單項下顯示存在的MDI窗體菜單項,點擊小圖放大

  三.程序源代碼(mdi.cs)及編譯方法:
  通過對程序設計中的難點介紹以后,就可以比較容易得到實現對上述MDI窗體處理的源程序代碼(mdi.cs),具體如下:
  mdi.cs源程序代碼:
復制代碼
  using  System ;
  using System.Windows.Forms ;
  using System.ComponentModel ;
  using System.Drawing ;
  //導入在程序中用到的名稱空間
  class MDIDemo : Form
  {
  private static int FormCount = 1 ;
  //定義此常量是為了統計MDI窗體數目,
  MainMenu mnuMain = new MainMenu ( ) ;
  MenuItem FileMenu ;
  MenuItem NewMenu ;
  MenuItem ExitMenu ;
  MenuItem WindowMenu ;

  public MDIDemo ( )
  {
  this.IsMdiContainer = true ;
  this.Text = "MDI演示程序" ;
  FileMenu =  new MenuItem ( ) ;
  FileMenu.Text = "文件" ;
  WindowMenu = new MenuItem ( ) ;
  WindowMenu.Text = "窗口(&W)" ;
  WindowMenu.MenuItems.Add ( "窗體層疊(&C)" , new EventHandler ( Cascade_Click ) ) ;
  WindowMenu.MenuItems.Add ( "水平平鋪(&H)" , new EventHandler ( TileH_Click ) ) ;
  WindowMenu.MenuItems.Add ( "垂直平鋪(&V)" , new EventHandler ( TileV_Click ) ) ;
  WindowMenu.MdiList = true ;
  //這一句比較重要,有了這一句就可以實現在新建一個MDI窗體后會在此主菜單項下顯示存在的MDI窗體菜單項
  NewMenu =  new MenuItem ( ) ;
  NewMenu.Text = "新建窗體(&N)" ;
  NewMenu.Click += new EventHandler ( New_Click ) ;
  ExitMenu =  new MenuItem ( ) ;
  ExitMenu.Text = "退出(&X)" ;
  ExitMenu.Click += new EventHandler ( Exit_Click ) ;
  FileMenu.MenuItems.Add ( NewMenu ) ;
  FileMenu.MenuItems.Add ( new MenuItem ( "-" ) ) ;
  FileMenu.MenuItems.Add ( ExitMenu ) ;
  mnuMain.MenuItems.Add ( FileMenu ) ;
  mnuMain.MenuItems.Add ( WindowMenu ) ;
  this.Menu = mnuMain ;
  }

  private void Cascade_Click ( object sender , EventArgs e )
  //實現對主窗體中的MDI窗體的層疊操作
  {
  this.LayoutMdi ( MdiLayout.Cascade ) ;
  }

  private void TileH_Click ( object sender , EventArgs e )
  //實現對主窗體中的MDI窗體的水平平鋪操作
  {
  this.LayoutMdi ( MdiLayout.TileHorizontal ) ;
  }

  private void TileV_Click ( object sender , EventArgs e )
  //實現對主窗體中的MDI窗體的垂直平鋪操作
  {
  this.LayoutMdi ( MdiLayout.TileVertical ) ;
  }

  private void New_Click (  object sender , EventArgs e )
  {
  Form frmTemp = new Form ( ) ;
  //新建一個窗體
  frmTemp.MdiParent = this ;
  //定義此窗體的父窗體,從而此窗體成為一個MDI窗體
  frmTemp.Text = "窗體0" + FormCount.ToString ( ) ;
  //設定MDI窗體的標題
  FormCount++ ;
  frmTemp.Show ( ) ;
  //把此MDI窗體顯示出來
  }

  private void Exit_Click (  object sender , EventArgs e )
  {
  this.Dispose ( );
  Application.Exit ( ) ;
  }

  public static void Main ( )
  {
  Application.Run ( new MDIDemo ( ) ) ;
  }
  }
復制代碼

再經過以下編譯命令編譯過以后,就可以得到執行程序:
  csc /t:winexe /r:system.dll /r:system.windows.forms.dll /r:system.drawing.dll mdi.cs

四.總結:
  本文主要是介紹如何用Visual C#來實現對MDI窗體的編程。即:新建MDI窗體、MDI窗體層疊、MDI窗體水平平鋪、MDI窗體的垂直平鋪。通過上述介紹,可見,在Visual C#中處理MDI還是相當比較簡單的。
不過說實現在我不建議大家這樣實現了,而是喜歡使用Tabcontrol的方法,這樣容易控件,而且可以達到多任務,多操作的效果,也是目前幾乎所有瀏覽器都采用的方法

 

MDI窗體容器 - 放窗體的容器

窗體是頂級控件,是不允許放到其他的控件或窗體中的 (李獻策lxc)

窗體屬性中有一個屬性:IsMdiContainer - 確定該窗體是否是MDI容器

在窗體中放一個頂部菜單

點擊<銷售>按鈕會在窗體中彈出一個新的窗體

復制代碼
//銷售
        private void 銷售ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form5 f5 = new Form5();
            f5.MdiParent = this;
            f5.Show();
        }
復制代碼

內部窗體可以在父級窗體里任意移動

問題一:打開新的窗體全屏(李獻策lxc)

復制代碼
//銷售
        private void 銷售ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form5 f5 = new Form5();
            //窗體最大化
            f5.WindowState = FormWindowState.Maximized;

            f5.MdiParent = this;
            f5.Show();
        }
復制代碼

問題二:打開后有最小化、最大化等按鈕

錯誤方法一:去掉最大化最小化按鈕——失敗

復制代碼
//銷售
        private void 銷售ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form5 f5 = new Form5();
            //窗體最大化
            f5.WindowState = FormWindowState.Maximized;

            //去掉最大化最小化按鈕
            f5.MaximizeBox = false;
            f5.MinimizeBox = false;

            f5.MdiParent = this;
            f5.Show();
        }
復制代碼

錯誤方法二:去掉邊框——失敗(李獻策lxc)

復制代碼
//銷售
        private void 銷售ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form5 f5 = new Form5();
            //窗體最大化
            f5.WindowState = FormWindowState.Maximized;

            //去掉邊框
            f5.FormBorderStyle = FormBorderStyle.None;

            f5.MdiParent = this;
            f5.Show();
        }
復制代碼

正確方法:先用一個panel填充窗體剩余部分,在panel中打開新窗體

復制代碼
//銷售
        private void 銷售ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form5 f5 = new Form5();
            //窗體最大化
            f5.WindowState = FormWindowState.Maximized;

            //去掉邊框
            f5.FormBorderStyle = FormBorderStyle.None;

            f5.MdiParent = this;

            //設置新窗體的Parent
            f5.Parent = panel1;

            f5.Show();
        }
復制代碼

問題三:在即將打開的新窗體中放入一個button1,Anchor設置為Bottom,Right,當打開新窗體並拖動窗體邊框時,按鈕並未鎖定與底部和右側的距離

panel是跟隨窗體的變化而變化,但是新窗體是不隨panel變化而變化的 

  

解決方法:設置主窗體的size發生改變時新窗體同時改變size(李獻策lxc) 

復制代碼
//Size改變時的事件
        private void Form3_SizeChanged(object sender, EventArgs e)
        {
            //遍歷panel中的控件,
            foreach (var v in panel1.Controls)
            {
                //如果是新窗體
                if (v is Form5)
                {
                    //新窗體先變為正常大小
                    (v as Form5).WindowState = FormWindowState.Normal;
                    //新窗體再變為最大化以適應新的Size
                    (v as Form5).WindowState = FormWindowState.Maximized;
                }
            }
        }
復制代碼

問題四:在點擊<倉庫>按鈕時,會在主窗體中打開一個新的窗體,再點擊<銷售>按鈕會切回銷售窗體,但實際是又創建了一個新的銷售窗體而已,並非原來打開的窗體

解決辦法:唯一窗體(李獻策lxc)

==========================================================

權限設置 - 不同的權限登入時顯示內容不同

新建一個登入窗體

數據庫中添加一個新的權限表

 

1、首先設置父級Form1界面,只需要將該界面的IsMdiContainer屬性設置為true;

2、設置按鈕的事件來打開子級的窗口Form2,Form3等等;

3、在From1內設置一個容器panel,范圍為需要打開的子級界面的大小;

4、設置Form2、Form3的事件,以及唯一窗口等;

復制代碼
//Form2的點擊事件
        private void form2ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form2 f2 = new Form2();
            f2.Name = "f2";
            openwidow(f2);
        }
//Form3的點擊件
        private void form3ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form3 f3 = new Form3();
            f3.Name = "f3";
            openwidow(f3);
        }
//設置唯一窗口:
//新建一個formlist集合,供唯一窗口使用
List<Form> formlist = new List<Form>();
//新建一個public的方法
        private void openwidow(Form f)
        {
//定義一個Form fff變量
            Form fff = null;
//定義一個bool類型的變量為false;
            bool open = false;
//遍歷這個集合
            foreach (Form ff in listfrom)
            {
//只要遍歷到就隱藏
                ff.Hide();
//如果遍歷到f.name
                if (ff.Name == f.Name)
                {
                    open = true;
//把ff放到集合內
                    fff = ff;
                }
            }
//如果遍歷到f.name,
            if (open)
            {
//關閉所有窗口
                f.Close();
//重新打開這個串口
                fff.Show();
            }
//否則
            else
            {
//設置打開的窗口為Form1的子窗體;
                f.MdiParent = this;
//設置子窗口的大小為最大化;
                f.WindowState = FormWindowState.Maximized;
//把子窗口放到Form1的panel1里;
                f.Parent = panel1;
//設置無邊框
                f.FormBorderStyle = FormBorderStyle.None;
//打開窗口
                f.Show();
//把這個窗口放到集合內
                fromlist.Add(f);
            }

        }
復制代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM