Achieve left-side layout multi-window interface under winform-continuation, winform window
The previous article "Implementing left and right multi-window layout Interfaces under winform" has implemented left and right multi-window layout interfaces. Today we are studying winform-based plug-in programming, I did not expect to find another implementation scheme by the way. This implementation scheme is simpler and few code needs to be written. The specific implementation is as follows.
Visual Design:
1. Parent window: Set IsMdiContainer of ParentForm to true, that is, this. IsMdiContainer = true;
2. in the parent window, add menuStrip1, Windows, and set MdiWindowListItem of menuStrip1 as the Windows menu object, that is, this. menuStrip1.MdiWindowListItem = this. windowsToolStripMenuItem;
3. in the parent window, add a tree menu: treeView1 and set its Dock to align left, that is, this. treeView1.Dock = System. windows. forms. dockStyle. left; and set margin to 0;
4. Add a Panel: panel1 in the parent window and set its width to 3;
The following code is automatically generated after the design:
Namespace WinFormTest {partial class ParentForm {/// <summary> /// a required designer variable. /// </Summary> private System. ComponentModel. IContainer components = null; // <summary> /// clear all resources in use. /// </Summary> /// <param name = "disposing"> true if the managed resource should be released; otherwise, false. </Param> protected override void Dispose (bool disposing) {if (disposing & (components! = Null) {components. dispose ();} base. dispose (disposing );} # region Windows Form Designer generated code /// <summary> /// the designer supports the required methods-do not // use the code editor to modify the content of this method. /// </Summary> private void InitializeComponent () {this. menuStrip1 = new System. windows. forms. menuStrip (); this. windowsToolStripMenuItem = new System. windows. forms. toolStripMenuItem (); this. treeView1 = new System. windows. forms. treeView (); this. panel1 = new System. windows. forms. panel (); this. menuStrip1.SuspendLayout (); this. suspendLayout (); // menuStrip1 // this. menuStrip1.Items. addRange (new System. windows. forms. toolStripItem [] {this. windowsToolStripMenuItem}); this. menuStrip1.Location = new System. drawing. point (0, 0); this. menuStrip1.MdiWindowListItem = this. windowsToolStripMenuItem; this. menuStrip1.Name = "menuStrip1"; this. menuStrip1.Size = new System. drawing. size (684, 25); this. menuStrip1.TabIndex = 0; this. menuStrip1.Text = "menuStrip1"; // windowsToolStripMenuItem // this. windowsToolStripMenuItem. name = "windowsToolStripMenuItem"; this. windowsToolStripMenuItem. size = new System. drawing. size (73, 21); this. windowsToolStripMenuItem. text = "Windows"; // treeView1 // this. treeView1.Dock = System. windows. forms. dockStyle. left; this. treeView1.Location = new System. drawing. point (0, 25); this. treeView1.Margin = new System. windows. forms. padding (0); this. treeView1.Name = "treeView1"; this. treeView1.Size = new System. drawing. size (228,380); this. treeView1.TabIndex = 3; this. treeView1.NodeMouseDoubleClick + = new System. windows. forms. treeNodeMouseClickEventHandler (this. treeviewappsnodemousedoubleclick); // panel1 // this. panel1.Anchor = (System. windows. forms. anchorStyles) (System. windows. forms. anchorStyles. top | System. windows. forms. anchorStyles. bottom) | System. windows. forms. anchorStyles. left); this. panel1.BackColor = System. drawing. color. red; this. panel1.BorderStyle = System. windows. forms. borderStyle. fixedSingle; this. panel1.Cursor = System. windows. forms. cursors. VSplit; this. panel1.Location = new System. drawing. point (230, 28); this. panel1.Margin = new System. windows. forms. padding (0); this. panel1.Name = "panel1"; this. panel1.Size = new System. drawing. size (3,100); this. panel1.TabIndex = 5; // Form1 // this. autoScaleDimensions = new System. drawing. sizeF (6F, 12F); this. autoScaleMode = System. windows. forms. autoScaleMode. font; this. clientSize = new System. drawing. size (684,405); this. controls. add (this. panel1); this. controls. add (this. treeView1); this. controls. add (this. menuStrip1); this. isMdiContainer = true; this. mainMenuStrip = this. menuStrip1; this. name = "Form1"; this. text = "Form1"; this. load + = new System. eventHandler (this. form1_Load); this. resize + = new System. eventHandler (this. form1_Resize); this. menuStrip1.ResumeLayout (false); this. menustrip1.w.mlayout (); this. resumeLayout (false); this. extends mlayout () ;}# endregion private System. windows. forms. menuStrip menuStrip1; private System. windows. forms. toolStripMenuItem windowsToolStripMenuItem; private System. windows. forms. treeView treeView1; private System. windows. forms. panel panel1 ;}}
Encoding part:
In fact, after the above design, if you open a subwindow through the following defined method, the left and right layout is directly implemented and the interface contains multiple subwindows.
private void ShowChildForm<TForm>() where TForm : Form, new() { Form childForm = new TForm(); childForm.MdiParent = this; childForm.Name = "ChildForm - " + DateTime.Now.Millisecond.ToString(); childForm.Text = childForm.Name; childForm.Show(); }
Of course there are still imperfections, that is, the width of the Left menu bar cannot be dynamically adjusted, but splitContainer is not used. Therefore, we only need to implement it by ourselves. In fact, the steps are as follows:
1. Add the initialization panel1 (used as the splitter) position and subscribe to related events in the parent window constructor. The Code is as follows:
public ParentForm() { InitializeComponent(); panel1.MouseDown += panel1_MouseDown; panel1.MouseUp += panel1_MouseUp; panel1.MouseMove += panel1_MouseMove; panel1.Top = menuStrip1.Height; panel1.Left = treeView1.Left + treeView1.Width; panel1.Height = panel1.Parent.Height; }
The functions of the above Code are as follows: 1. Ensure that the height and position of panel1 match the left-side tree menu control; 2. The three Mouse events subscribed to are mainly used to implement Mobile panel1.
2. The methods corresponding to the three Mouse events subscribed to are Mouse press, Mouse move, and Mouse release. The Code is as follows:
Private bool startMove = false; // used to mark whether the void panelease mousemove (object sender, MouseEventArgs e) {if (startMove) {panel1.Left + = e. X ;}} void panel=mouseup (object sender, MouseEventArgs e) {if (startMove) {panel1.Left + = e. x; startMove = false; this. treeView1.Width = panel1.Left;} void panel=mousedown (object sender, MouseEventArgs e) {startMove = true ;}
The purpose of the above Code: press the mouse and mark it as start to move, and then move the mouse. If it is marked as moving, it means moving panel1, therefore, the current X coordinate position of the mouse is directly added to the panel1.Left attribute to move the mouse. When the mouse pops up, the width of the tree menu is set to panel1.Left, in this way, the size of the tree menu changes with the movement of panel1.
At the same time, to ensure that the height of panel1 is always the same as that of the tree menu, add the dynamic height adjustment of panel1 to the Resize method of the parent window. The Code is as follows:
private void ParentForm_Resize(object sender, EventArgs e) { panel1.Height = panel1.Parent.Height; }
This completes the entire implementation scheme. To facilitate the simulation of the effect of double-clicking the subwindow in the tree menu, the following code is also added:
Private void ParentForm_Load (object sender, EventArgs e) {LoadMenuNodes ();} private void LoadMenuNodes () // The menu item {this. treeView1.Nodes. clear (); var root = this. treeView1.Nodes. add ("Root"); for (int I = 1; I <= 10; I ++) {var section = root. nodes. add ("Section-" + I); int maxNodes = new Random (I ). next (1, 10); for (int n = 1; n <= maxNodes; n ++) {section. nodes. add (string. format ("Level-{0}-{1}", I, n) ;}} private void treeView1_NodeMouseDoubleClick (object sender, TreeNodeMouseClickEventArgs e) {if (e. node. nodes. count <= 0) // when a non-parent node (that is, the actual functional node) {ShowChildForm <ChildForm> ();}}
Complete implementation code is attached:
Using System; using System. collections. generic; using System. componentModel; using System. data; using System. drawing; using System. linq; using System. text; using System. threading. tasks; using System. windows. forms; namespace WinFormTest {public partial class ParentForm: Form {private bool startMove = false; public ParentForm () {InitializeComponent (); panel1.MouseDown + = panel=mousedown; panel1.MouseUp + = panel=mouseup; panel1.MouseMove + = panel1_MouseMove; panel1.Top = menuStrip1.Height; panel1.Left = treeView1.Left + treeView1.Width; panel1.Height = panel1.Parent. height;} void panel1_MouseMove (object sender, MouseEventArgs e) {if (startMove) {panel1.Left + = e. X ;}} void panel=mouseup (object sender, MouseEventArgs e) {if (startMove) {panel1.Left + = e. x; startMove = false; this. treeView1.Width = panel1.Left;} void panel=mousedown (object sender, MouseEventArgs e) {startMove = true;} private void ParentForm_Load (object sender, EventArgs e) {LoadMenuNodes ();} private void treeView1_NodeMouseDoubleClick (object sender, TreeNodeMouseClickEventArgs e) {if (e. node. nodes. count <= 0) // when a non-parent node (that is, the actual function node) {ShowChildForm <ChildForm> () ;}} private void ParentForm_Resize (object sender, EventArgs e) {panel1.Height = panel1.Parent. height;} private void LoadMenuNodes () // The menu item {this. treeView1.Nodes. clear (); var root = this. treeView1.Nodes. add ("Root"); for (int I = 1; I <= 10; I ++) {var section = root. nodes. add ("Section-" + I); int maxNodes = new Random (I ). next (1, 10); for (int n = 1; n <= maxNodes; n ++) {section. nodes. add (string. format ("Level-{0}-{1}", I, n) ;}} private void ShowChildForm <TForm> () where TForm: Form, new () {Form childForm = new TForm (); childForm. mdiParent = this; childForm. name = "ChildForm-" + DateTime. now. millisecond. toString (); childForm. text = childForm. name; childForm. show ();}}}
The final result is shown as follows:
Note: In order to reflect the splitter, I set the background color to red for your convenience. This solution has the same functions as the previous solution, but there is a slight difference, in the previous solution, the title bar of the subwindow is in the container of the parent window. In this solution, when the subwindow is maximized, the title bar of the subwindow will be merged with the parent window, as shown in, which is applicable to actual scenarios.
In the future, I will continue to study winform plug-in programming (Requirements for recent work tasks). I will share it with you at that time. You are also welcome to join us. Of course, you can ignore it.