首页 > 其他分享 >分享在winform下实现左右布局多窗口界面-续篇

分享在winform下实现左右布局多窗口界面-续篇

时间:2022-09-20 11:56:53浏览次数:95  
标签:treeView1 续篇 menuStrip1 Windows 多窗口 System new panel1 winform

之前的这篇文章《分享在winform下实现左右布局多窗口界面》已经实现了左右布局多窗口界面,今天本来是研究基于winform的插件编程,没想到顺便又找到了另一种实现方案,这种实现方案更简单,要写的代码也很少,具体实现如下。

可视化设计部份:

1.父窗口:ParentForm的IsMdiContainer 设置为 true,即:this.IsMdiContainer=true;

2.在父窗口中添加一个顶部菜单:menuStrip1,并新增一个菜单项:Windows,且将menuStrip1的MdiWindowListItem设置为该Windows菜单对象,即: this.menuStrip1.MdiWindowListItem = this.windowsToolStripMenuItem;

3.在父窗口中添加一个树形菜单:treeView1,并将其Dock设为左靠齐,即:this.treeView1.Dock = System.Windows.Forms.DockStyle.Left;且将margin设为0;

4.在父窗口中添加一个Panel:panel1,且将其width设为3;

以下是设计后自动生成的代码:

+ View Code?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 namespace WinFormTest {     partial class ParentForm     {         /// <summary>         /// 必需的设计器变量。         /// </summary>         private System.ComponentModel.IContainer components = null;           /// <summary>         /// 清理所有正在使用的资源。         /// </summary>         /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>         protected override void Dispose(bool disposing)         {             if (disposing && (components != null))             {                 components.Dispose();             }             base.Dispose(disposing);         }           #region Windows 窗体设计器生成的代码           /// <summary>         /// 设计器支持所需的方法 - 不要         /// 使用代码编辑器修改此方法的内容。         /// </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.treeView1_NodeMouseDoubleClick);                           //             // 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.PerformLayout();             this.ResumeLayout(false);             this.PerformLayout();           }           #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;     } }

编码部份:

其实上面的设计后,如果通过以下定义的方法打开一个子窗口,则直接实现了左右布局且包含多子窗口的界面。

?
1 2 3 4 5 6 7 8 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(); }

当然仍然有不完美的地方,那就是左边菜单栏宽度不能动态调整,而又没有用到splitContainer,故我们只有自己来实现,其实也很简单,步骤如下: 

1.在父窗口构造函数中加入初始化panel1(用作分割器)位置及订阅相关事件,代码如下:

?
1 2 3 4 5 6 7 8 9 10 11 12 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; }

上述代码的作用是:1.保证panel1的高度与位置与左侧树形菜单控件相匹配;2.订阅的三个Mouse事件主要是为了后面实现移动panel1。

2.实现订阅的三个Mouse事件所对应的方法,分别为鼠标按下、鼠标移动、鼠标松开,代码如下:

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 private bool startMove = false; //用于标记是否在移动中           void panel1_MouseMove(object sender, MouseEventArgs e)         {             if (startMove)             {                 panel1.Left += e.X;             }         }           void panel1_MouseUp(object sender, MouseEventArgs e)         {             if (startMove)             {                 panel1.Left += e.X;                 startMove = false;                 this.treeView1.Width = panel1.Left;             }         }           void panel1_MouseDown(object sender, MouseEventArgs e)         {             startMove = true;         }

上述代码作用:按下鼠标标记为开始移动,然后移动鼠标,若是标记移动中,说明是要移动panel1,故直接将鼠标当前的X坐标位置累加到panel1.Left属性上,从而实现移动,当鼠标弹起后,则将树形菜单的宽度设置为panel1.Left,从而实现树形菜单随panel1的移动而改变大小。

同时为了保证panel1的高度始终与树形菜单相同,在父窗口的Resize方法加入动态调整panel1的高度,代码如下:

?
1 2 3 4 private void ParentForm_Resize(object sender, EventArgs e) {     panel1.Height = panel1.Parent.Height; }

到此就完成了整个的实现方案,为了便于模拟在树形菜单中双击打开子窗口的效果,同时也添加了如下代码:

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 private void ParentForm_Load(object sender, EventArgs e) {     LoadMenuNodes(); }     private void LoadMenuNodes() //实现情况应该是从数据库及用户权限来进行动态创建菜单项 {     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)//当非父节点(即:实际的功能节点)     {         ShowChildForm<ChildForm>();     } }

附上完整的实现代码:

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 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 += 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;         }           void panel1_MouseMove(object sender, MouseEventArgs e)         {             if (startMove)             {                 panel1.Left += e.X;             }         }           void panel1_MouseUp(object sender, MouseEventArgs e)         {             if (startMove)             {                 panel1.Left += e.X;                 startMove = false;                 this.treeView1.Width = panel1.Left;             }         }           void panel1_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)//当非父节点(即:实际的功能节点)             {                 ShowChildForm<ChildForm>();             }         }           private void ParentForm_Resize(object sender, EventArgs e)         {             panel1.Height = panel1.Parent.Height;         }           private void LoadMenuNodes() //实现情况应该是从数据库及用户权限来进行动态创建菜单项         {             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();         }     } }

最终效果如下图示:

 

说明:我这里为了体现分割器,故将其背景色设为红色,便于大家观察,这种解决方案与之前的解决方案功能上是相同的,但有一点小小区别,之前的解决方案中子窗口的标题栏是在父窗口的容器内,而本文的解决方案中子窗口在最大化后,子窗口的标题栏会与父窗口合并,如下图示,至于大家用哪种依实际场景。

后续时间我会继续研究winform关于插件式编程(近期工作任务要求),到时候同样会分享给大家,也欢迎大家一起交流,当然高手可以无视。

 

出处:https://www.cnblogs.com/zuowj/p/5225814.html

标签:treeView1,续篇,menuStrip1,Windows,多窗口,System,new,panel1,winform
From: https://www.cnblogs.com/mq0036/p/16710534.html

相关文章

  • Winform应用程序实现通用消息窗口
    记得我之前发表过一篇文章《Winform应用程序实现通用遮罩层》,是实现了透明遮罩的消息窗口,功能侧重点在动图显示+消息提醒,效果看上去比较的炫,而本篇我又来重新设计通用消息......
  • 两种实现Winform程序的多语言支持的解决方案
    因公司业务需要,需要将原有的ERP系统加上支持繁体语言,但不能改变原有的编码方式,即:普通程序员感受不到编码有什么不同。经过我与几个同事的多番沟通,确定了以下两种方案:方案......
  • Winform自定义窗体标题栏样式
    最近在编写C/S结构应用程序时,感觉窗体的标题栏样式太死板了,标题文字不能更改大小、颜色、字体等,按钮不能隐藏等问题,在网上也查找了许多相关的资料,没有找到合适的解决方案,......
  • C# WinForm DataGridView根据某一列值改变行颜色
    DataGridView根据某一列值改变行颜色,需要同时用到事件:CurrentCellDirtyStateChanged和CellValueChangedprivatevoiddgv1_CellValueChanged(objectsender,D......
  • C# WinForm 按名称查找控件
    1///<summary>2///按名称查找控件3///</summary>4///<paramname="parentControl">查找控件的父容器控件</param>5///<paramname="findCtrlName">查......
  • C# winform 配置log4net
    Winform配置了Log4net但是总是不能输出,是log4net.config配置文件访问路径出错了。 就是程序在运行时候没把log4net.config配置文件复制到Debug文件夹下,导致log4net访问......
  • Winform窗体之间传值
    1.构造函数传值创建窗体,默认都有一个无参构造方法,手动新增两个参数的构造方法Form1publicpartialclassForm1:Form{publicForm1(){......
  • 桌面应用程序Exe 是带有WinForm界面的。
    作者:小辣椒高效Office链接:https://www.zhihu.com/question/547458931/answer/2617110629来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。......
  • .NET|--Winform|--Form的Size失效 宽度不能小于132
    解决方案最近在浏览帖子的时候无意间发现,把form的MinimumSize属性设为1,1后,可以把窗口设置最小到1,1的大小,也就可以解决这个问题了。个人猜测,系统中应该有设置窗口最小宽......
  • 界面控件DevExpress WinForms & WPF v22.2——全新的.NET和ARM支持
    DevExpressWinForm拥有180+组件和UI库,能为WindowsForms平台创建具有影响力的业务解决方案。DevExpressWinForms能完美构建流畅、美观且易于使用的应用程序,无论是Office......