在C#中,可以使用Windows Forms或WPF来设计带有导航菜单的主界面。
一、关于导航菜单
导航菜单是一种用户界面元素,用于帮助用户在应用程序的不同部分之间进行导航。它通常包含一个或多个菜单项,每个菜单项都表示一个特定的功能或操作。当用户单击某个菜单项时,应用程序会执行相应的操作或显示与该操作相关的子菜单。
导航菜单可以出现在应用程序的顶部、底部或侧边,具体取决于应用程序的设计和平台。例如,在Web应用程序中,导航菜单通常出现在页面的顶部或侧边,而在移动应用程序中,导航菜单可能出现在屏幕的底部或顶部。
导航菜单的主要目的是提供一个直观且一致的方式来访问应用程序的主要功能和特性。它可以帮助用户快速找到他们需要的信息或完成特定的任务,从而提高应用程序的可用性和用户体验。
二、设计一个带导航菜单的主界面
在窗体中添加一个MenuStrip控件,用来设计菜单栏;添加一个SplitContainer控件,用来将窗体分为两部分;添加一个ListView控件和3个Button控件,并将它们加入SqlitContainer1的左侧部分,用来制作窗体左侧的导航栏;添加一个ImageList组件,用来为ListView列表项提供图标。
1.Resources.Designer.cs设计
在图片资源管理器中设计项目需要的背景图片和ImageList组件的图片。
如何加载图片资源详见本文作者写的其他文章:C#手动改变自制窗体的大小
// Resources.Designer.cs //------------------------------------------------------------------------------ // <auto-generated> // 此代码由工具生成。 // 运行时版本:4.0.30319.42000 // // 对此文件的更改可能会导致不正确的行为,并且如果 // 重新生成代码,这些更改将会丢失。 // </auto-generated> //------------------------------------------------------------------------------ namespace _176.Properties { using System; /// <summary> /// 一个强类型的资源类,用于查找本地化的字符串等。 /// </summary> // 此类是由 StronglyTypedResourceBuilder // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen // (以 /str 作为命令选项),或重新生成 VS 项目。 [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Resources() { } /// <summary> /// 返回此类使用的缓存的 ResourceManager 实例。 /// </summary> [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("_176.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } /// <summary> /// 重写当前线程的 CurrentUICulture 属性,对 /// 使用此强类型资源类的所有资源查找执行重写。 /// </summary> [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } /// <summary> /// 查找 System.Drawing.Bitmap 类型的本地化资源。 /// </summary> internal static System.Drawing.Bitmap _1 { get { object obj = ResourceManager.GetObject("_1", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// <summary> /// 查找 System.Drawing.Bitmap 类型的本地化资源。 /// </summary> internal static System.Drawing.Bitmap _2 { get { object obj = ResourceManager.GetObject("_2", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// <summary> /// 查找 System.Drawing.Bitmap 类型的本地化资源。 /// </summary> internal static System.Drawing.Bitmap _3 { get { object obj = ResourceManager.GetObject("_3", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// <summary> /// 查找 System.Drawing.Bitmap 类型的本地化资源。 /// </summary> internal static System.Drawing.Bitmap _4 { get { object obj = ResourceManager.GetObject("_4", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// <summary> /// 查找 System.Drawing.Bitmap 类型的本地化资源。 /// </summary> internal static System.Drawing.Bitmap _5 { get { object obj = ResourceManager.GetObject("_5", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// <summary> /// 查找 System.Drawing.Bitmap 类型的本地化资源。 /// </summary> internal static System.Drawing.Bitmap _6 { get { object obj = ResourceManager.GetObject("_6", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// <summary> /// 查找 System.Drawing.Bitmap 类型的本地化资源。 /// </summary> internal static System.Drawing.Bitmap _7 { get { object obj = ResourceManager.GetObject("_7", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// <summary> /// 查找 System.Drawing.Bitmap 类型的本地化资源。 /// </summary> internal static System.Drawing.Bitmap _8 { get { object obj = ResourceManager.GetObject("_8", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// <summary> /// 查找 System.Drawing.Bitmap 类型的本地化资源。 /// </summary> internal static System.Drawing.Bitmap _9 { get { object obj = ResourceManager.GetObject("_9", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// <summary> /// 查找 System.Drawing.Bitmap 类型的本地化资源。 /// </summary> internal static System.Drawing.Bitmap C_编程词典 { get { object obj = ResourceManager.GetObject("C_编程词典", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } internal static Bitmap GetObject(string v) { return v switch { "C_编程词典" => C_编程词典, "_9" => _9, "_8" => _8, "_7" => _7, "_6" => _6, "_5" => _5, "_4" => _4, "_3" => _3, "_2" => _2, "_1" => _1, _ => null }; } } }
2.主要的设计步骤
(1)窗体静态设计
设计一个窗体;
在窗体中设计一个menustrip1控件,默认的控件位于Form1的顶部,重要的设置menustrip1控件的Dock属性设置为Top;最后设计3个MenuItem子控件:设置、打开、编辑;
在窗体剩余空间中添加一个 splitContainer控件,之所以说剩余空间,就是要保证menustrip1控件不被 splitContainer控件包含,这哈斯有menustrip1的Dock属性保证的;
设计图片资源管理器,并给右侧的splitContainer2添加背景图片,Stretch布局;
在左侧的splitContainer2控件里,添加3个button控件,并命名为:设置、打开、编辑;设置控件的Dock属性为Top,设置编辑控件的Dock属性为Top,最后,设置打开按钮的Dock属性为Top;结果是,设置按钮位于splitContainer2控件顶部,编辑按钮位于splitContainer2控件底部,打开按钮位于编辑按钮的顶部;这样的设置很重要;
在左侧的splitContainer2控件里设置按钮和打开按钮之间添加 listView1控件,其Dock属性设置为Fill,这很重要;
添加imageList1控件,并为其添加图片集;
设置 listView1控件的属性,右上角的尖角,选择大图标、imageList1、imageList1;
创建窗体、按钮1~3的Click事件;
// Form1.Designer.cs namespace _176 { partial class Form1 { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; 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> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1)); imageList1 = new ImageList(components); menuStrip1 = new MenuStrip(); toolStripMenuItem1 = new ToolStripMenuItem(); toolStripMenuItem2 = new ToolStripMenuItem(); toolStripMenuItem3 = new ToolStripMenuItem(); splitContainer1 = new SplitContainer(); listView1 = new ListView(); button3 = new Button(); button2 = new Button(); button1 = new Button(); menuStrip1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)splitContainer1).BeginInit(); splitContainer1.Panel1.SuspendLayout(); splitContainer1.SuspendLayout(); SuspendLayout(); // // imageList1 // imageList1.ColorDepth = ColorDepth.Depth32Bit; imageList1.ImageStream = (ImageListStreamer)resources.GetObject("imageList1.ImageStream"); imageList1.TransparentColor = Color.Transparent; imageList1.Images.SetKeyName(0, "1.png"); imageList1.Images.SetKeyName(1, "2.jpg"); imageList1.Images.SetKeyName(2, "3.png"); imageList1.Images.SetKeyName(3, "4.png"); imageList1.Images.SetKeyName(4, "5.png"); imageList1.Images.SetKeyName(5, "6.png"); imageList1.Images.SetKeyName(6, "7.png"); imageList1.Images.SetKeyName(7, "8.png"); imageList1.Images.SetKeyName(8, "9.png"); // // menuStrip1 // menuStrip1.Items.AddRange(new ToolStripItem[] { toolStripMenuItem1, toolStripMenuItem2, toolStripMenuItem3 }); menuStrip1.Location = new Point(0, 0); menuStrip1.Name = "menuStrip1"; menuStrip1.Size = new Size(434, 25); menuStrip1.TabIndex = 0; menuStrip1.Text = "menuStrip1"; // // toolStripMenuItem1 // toolStripMenuItem1.Name = "toolStripMenuItem1"; toolStripMenuItem1.Size = new Size(44, 21); toolStripMenuItem1.Text = "设置"; // // toolStripMenuItem2 // toolStripMenuItem2.Name = "toolStripMenuItem2"; toolStripMenuItem2.Size = new Size(44, 21); toolStripMenuItem2.Text = "打开"; // // toolStripMenuItem3 // toolStripMenuItem3.Name = "toolStripMenuItem3"; toolStripMenuItem3.Size = new Size(44, 21); toolStripMenuItem3.Text = "编辑"; // // splitContainer1 // splitContainer1.Dock = DockStyle.Fill; splitContainer1.Location = new Point(0, 25); splitContainer1.Name = "splitContainer1"; // // splitContainer1.Panel1 // splitContainer1.Panel1.Controls.Add(listView1); splitContainer1.Panel1.Controls.Add(button3); splitContainer1.Panel1.Controls.Add(button2); splitContainer1.Panel1.Controls.Add(button1); // // splitContainer1.Panel2 // splitContainer1.Panel2.BackgroundImage = Properties.Resources.C_编程词典; splitContainer1.Panel2.BackgroundImageLayout = ImageLayout.Stretch; splitContainer1.Size = new Size(434, 276); splitContainer1.SplitterDistance = 144; splitContainer1.TabIndex = 1; // // listView1 // listView1.Dock = DockStyle.Fill; listView1.LargeImageList = imageList1; listView1.Location = new Point(0, 23); listView1.Name = "listView1"; listView1.Size = new Size(144, 207); listView1.SmallImageList = imageList1; listView1.TabIndex = 3; listView1.UseCompatibleStateImageBehavior = false; // // button3 // button3.Dock = DockStyle.Bottom; button3.Location = new Point(0, 230); button3.Name = "button3"; button3.Size = new Size(144, 23); button3.TabIndex = 2; button3.Text = "编辑"; button3.UseVisualStyleBackColor = true; button3.Click += Button3_Click; // // button2 // button2.Dock = DockStyle.Bottom; button2.Location = new Point(0, 253); button2.Name = "button2"; button2.Size = new Size(144, 23); button2.TabIndex = 1; button2.Text = "打开"; button2.UseVisualStyleBackColor = true; button2.Click += Button2_Click; // // button1 // button1.Dock = DockStyle.Top; button1.Location = new Point(0, 0); button1.Name = "button1"; button1.Size = new Size(144, 23); button1.TabIndex = 0; button1.Text = "设置"; button1.UseVisualStyleBackColor = true; button1.Click += Button1_Click; // // Form1 // AutoScaleDimensions = new SizeF(7F, 17F); AutoScaleMode = AutoScaleMode.Font; ClientSize = new Size(434, 301); Controls.Add(splitContainer1); Controls.Add(menuStrip1); MainMenuStrip = menuStrip1; Name = "Form1"; StartPosition = FormStartPosition.CenterScreen; Text = "带导航菜单的窗体"; Load += Form1_Load; menuStrip1.ResumeLayout(false); menuStrip1.PerformLayout(); splitContainer1.Panel1.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)splitContainer1).EndInit(); splitContainer1.ResumeLayout(false); ResumeLayout(false); PerformLayout(); } #endregion private ImageList imageList1; private MenuStrip menuStrip1; private ToolStripMenuItem toolStripMenuItem1; private ToolStripMenuItem toolStripMenuItem2; private ToolStripMenuItem toolStripMenuItem3; private SplitContainer splitContainer1; private ListView listView1; private Button button3; private Button button2; private Button button1; } }
(2)事件的动作设计
// Form1.cs namespace _176 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } /// <summary> /// 默认设置 /// </summary> private void Form1_Load(object sender, EventArgs e) { listView1.Clear(); listView1.LargeImageList = imageList1; //设置当前项以大图标的形式显示时用到的图像 listView1.Items.Add("设置上下班时间", "设置上下班时间", 0); //向listView1中添加项“设置上下班时间” listView1.Items.Add("是否启用短信提醒", "是否启用短信提醒", 1);//向listView1中添加项“是否启用短信提醒” listView1.Items.Add("设置密码", "设置密码", 2); //向listView1中添加项“设置密码” } /// <summary> /// 设置 /// </summary> private void Button1_Click(object sender, EventArgs e) { listView1.Dock = DockStyle.None; //设置listView1的绑定属性为未绑定 button1.Dock = DockStyle.Top; //设置button1的绑定属性为上端绑定 button2.Dock = DockStyle.Bottom; //设置button2的绑定属性为底端绑定 button3.SendToBack(); //将button3发送到Z顺序的后面 button3.Dock = DockStyle.Bottom; //设置button3的绑定属性为底端绑定 listView1.BringToFront(); //将listView1带到Z顺序的前面 listView1.Dock = DockStyle.Bottom; //设置listView1的绑定属性为底端绑定 listView1.Clear(); listView1.Items.Add("设置上下班时间", "设置上下班时间", 0); listView1.Items.Add("是否启用短信提醒", "是否启用短信提醒", 1); listView1.Items.Add("设置密码", "设置密码", 2); } /// <summary> /// 打开 /// </summary> private void Button2_Click(object sender, EventArgs e) { listView1.Dock = DockStyle.None; //设置listView1的绑定属性为未绑定 button2.Dock = DockStyle.Top; //设置button2的绑定属性为上端绑定 button1.SendToBack(); //将控件button1发送到Z顺序的后面 button1.Dock = DockStyle.Top; //设置button1的绑定属性为上端绑定 button3.Dock = DockStyle.Bottom; //设置button3的绑定属性为底端绑定 listView1.Dock = DockStyle.Bottom;//设置listView1的绑定属性为底端绑定 listView1.Clear(); listView1.Items.Add("近期工作记录", "近期工作记录", 3); listView1.Items.Add("近期工作计划", "近期工作计划", 4); } /// <summary> /// 编辑 /// </summary> private void Button3_Click(object sender, EventArgs e) { listView1.Dock = DockStyle.None; //设置listView1的绑定属性为未绑定 button3.SendToBack(); //将button3发送到Z顺序的后面 button3.Dock = DockStyle.Top; //设置button3的绑定属性为上端绑定 button2.SendToBack(); //将button2发送到Z顺序的后面 button2.Dock = DockStyle.Top; //设置button2的绑定属性为上端绑定 button1.SendToBack(); //将button1发送到Z顺序的后面 button1.Dock = DockStyle.Top; //设置button1的绑定属性为上端绑定 listView1.Dock = DockStyle.Bottom; //设置listView1的绑定属性为底端绑定 listView1.Clear(); listView1.Items.Add("编辑工作进度报告", "编辑工作进度报告", 5); listView1.Items.Add("编辑项目设计图", "编辑项目设计图", 6); } } }
3.涉及到的主要知识点
(1)Control.SendToBack 方法
将控件发送到 Z 顺序的后面。
public void SendToBack ();
控件移动到 z 顺序的后面。 如果控件是另一个控件的子控件,则子控件将移动到 z 顺序的后面。 如果控件是顶级控件,则除非控件处于活动状态,否则此方法将无法正常工作。 顶级控件是一个控件,如 Form,它不是另一个控件的子控件。 活动控件是具有输入焦点的可见控件。 若要将 SendToBack 方法与非活动顶级控件一起使用,请先对 控件调用 BringToFront 方法。
(2)Control.BringToFront 方法
将控件带到 Z 顺序的前面。
public void BringToFront ();
控件将移动到 z 顺序的前面。 如果控件是另一个控件的子控件,则子控件将移动到 z 顺序的前面。 BringToFront 不会使控件成为顶级控件,也不会引发 Paint 事件。
(3)Control.UpdateZOrder 方法
按其父级的 z 顺序更新控件。
protected void UpdateZOrder ();
UpdateZOrder 方法更新控件在其父控件的 z 顺序中的位置。例如,如果此控件是添加到 Control.ControlCollection 中的新创建的控件,则 z 顺序将更新为添加到后面的新控件。
(4) ListView控件的Items.Add方法
ListView控件的Items属性用来获取包含控件中所有项的集合,其Add方法用来将项添加到ListView列表中。
public virtual ListViewltem Add(string key,string text,int imagelndex)
参 数 | 说 明 | 参 数 | 说 明 |
---|---|---|---|
key | 项的名称 | imageIndex | 要为该项显示的图像的索引 |
text | 项的文本 | 返回值 | 添加到集合中的ListViewItem |
5) Z-Order
C# 中的 Z-Order 是一种确定窗口或控件在屏幕上的堆叠顺序的方式。它由窗口或控件在坐标系中的 Z 值决定。具有更高 Z 值的窗口或控件位于具有较低 Z 值的窗口或控件之上。
在 C# 中,您可以使用 SendToBack 方法将指定控件发送到 Z-Order 的末尾,这意味着它将位于所有其他控件之后。这在您想要创建一个透明窗口或控件,并且需要将其放在其他所有控件之后的情况下非常有用。