(十三)c#Winform自定义控件-导航菜单

本文介绍如何在C# Winform应用中制作一个自定义的导航菜单,包括父节点和子节点的实现,通过接口定义节点样式,并提供了完整的代码示例。该菜单控件支持二级导航,可以方便地控制节点展示效果。
摘要由CSDN通过智能技术生成

前提

入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。

GitHub:https://github.com/kwwwvagaa/NetWinformControl

码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git

如果觉得写的还行,请点个 star 支持一下吧

欢迎前来交流探讨: 企鹅群568015492 企鹅群568015492

目录

https://www.cnblogs.com/bfyx/p/11364884.html

准备工作

有时候我们需要左侧的导航菜单,那么来整一个吧

先来分析分析,导航菜单一般分为2级或多级,如果是多级的话 用前面的treeview更合适,这里只做2级,为了父子节点样式更方便控制,我们分别实现父子节点。

为了更加的Open,我们使用接口来定义一下

开始

定义一个节点数据绑定实体

 1     [Serializable]
 2     public class MenuItemEntity
 3     {
 4         /// <summary>
 5         /// 6         /// </summary>
 7         public string Key { get; set; }
 8         /// <summary>
 9         /// 文字
10         /// </summary>
11         public string Text { get; set; }
12         /// <summary>
13         /// 子节点
14         /// </summary>
15         public List<MenuItemEntity> Childrens { get; set; }
16         /// <summary>
17         /// 自定义数据源,一般用于扩展展示,比如定义节点图片等
18         /// </summary>
19         public object DataSource { get; set; }
20 
21     }

再定义一个接口来约束

 1  public interface IMenuItem
 2     {
 3         event EventHandler SelectedItem;
 4         MenuItemEntity DataSource { get; set; }
 5         /// <summary>
 6         /// 设置样式
 7         /// </summary>
 8         /// <param name="styles">key:属性名称,value:属性值</param>
 9         void SetStyle(Dictionary<string, object> styles);
10         /// <summary>
11         /// 设置选中样式
12         /// </summary>
13         /// <param name="blnSelected">是否选中</param>
14         void SetSelectedStyle(bool blnSelected);
15     }

首先看父节点定义,添加一个用户控件,命名UCMenuParentItem,并且实现接口IMenuItem

  public event EventHandler SelectedItem;

        private MenuItemEntity m_dataSource;
        public MenuItemEntity DataSource
        {
            get
            {
                return m_dataSource;
            }
            set
            {
                m_dataSource = value;
                if (value != null)
                {
                    lblTitle.Text = value.Text;
                }
            }
        }
 public void SetStyle(Dictionary<string, object> styles)
        {
            Type t = this.GetType();
            foreach (var item in styles)
            {
                var pro = t.GetProperty(item.Key);
                if (pro != null && pro.CanWrite)
                {
                    try
                    {
                        pro.SetValue(this, item.Value, null);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("菜单元素设置样式异常", ex);
                    }
                }
            }
        }

        public void SetSelectedStyle(bool blnSelected)
        {
            if (blnSelected)
            {
                this.lblTitle.Image = Properties.Resources.sanjiao1;
            }
            else
            {
                this.lblTitle.Image = Properties.Resources.sanjiao2;
            }
        }

然后处理下点击事件

 lblTitle.MouseDown += lblTitle_MouseDown;

  void lblTitle_MouseDown(object sender, MouseEventArgs e)
        {
            if (SelectedItem != null)
            {
                SelectedItem(this, e);
            }
        }

这样就完事了,看下完整代码

 1 // 版权所有  黄正辉  交流群:568015492   QQ:623128629
 2 // 文件名称:UCMenuParentItem.cs
 3 // 创建日期:2019-08-15 16:02:35
 4 // 功能描述:Menu
 5 // 项目地址:https://gitee.com/kwwwvagaa/net_winform_custom_control
 6 using System;
 7 using System.Collections.Generic;
 8 using System.ComponentModel;
 9 using System.Drawing;
10 using System.Data;
11 using System.Linq;
12 using System.Text;
13 using System.Windows.Forms;
14 
15 namespace HZH_Controls.Controls
16 {
17     /// <summary>
18     /// 父类节点
19     /// </summary>
20     [ToolboxItem(false)]
21     public partial class UCMenuParentItem : UserControl, IMenuItem
22     {
23         public event EventHandler SelectedItem;
24 
25         private MenuItemEntity m_dataSource;
26         public MenuItemEntity DataSource
27         {
28             get
29             {
30                 return m_dataSource;
31             }
32             set
33             {
34                 m_dataSource = value;
35                 if (value != null)
36                 {
37                     lblTitle.Text = value.Text;
38                 }
39             }
40         }
41 
42         public UCMenuParentItem()
43         {
44             InitializeComponent();
45             lblTitle.MouseDown += lblTitle_MouseDown;
46         }
47 
48         public void SetStyle(Dictionary<string, object> styles)
49         {
50             Type t = this.GetType();
51             foreach (var item in styles)
52             {
53                 var pro = t.GetProperty(item.Key);
54                 if (pro != null && pro.CanWrite)
55                 {
56                     try
57                     {
58                         pro.SetValue(this, item.Value, null);
59                     }
60                     catch (Exception ex)
61                     {
62                         throw new Exception("菜单元素设置样式异常", ex);
63                     }
64                 }
65             }
66         }
67 
68         public void SetSelectedStyle(bool blnSelected)
69         {
70             if (blnSelected)
71             {
72                 this.lblTitle.Image = Properties.Resources.sanjiao1;
73             }
74             else
75             {
76                 this.lblTitle.Image = Properties.Resources.sanjiao2;
77             }
78         }
79 
80         void lblTitle_MouseDown(object sender, MouseEventArgs e)
81         {
82             if (SelectedItem != null)
83             {
84                 SelectedItem(this, e);
85             }
86         }
87     }
88 }
View Code
 1 namespace HZH_Controls.Controls
 2 {
 3     partial class UCMenuParentItem
 4     {
 5         /// <summary> 
 6         /// 必需的设计器变量。
 7         /// </summary>
 8         private System.ComponentModel.IContainer components = null;
 9 
10         /// <summary> 
11         /// 清理所有正在使用的资源。
12         /// </summary>
13         /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
14         protected override void Dispose(bool disposing)
15         {
16             if (disposing && (components != null))
17             {
18                 components.Dispose();
19             }
20             base.Dispose(disposing);
21         }
22 
23         #region 组件设计器生成的代码
24 
25         /// <summary> 
26         /// 设计器支持所需的方法 - 不要
27         /// 使用代码编辑器修改此方法的内容。
28         /// </summary>
29         private void InitializeComponent()
30         {
31             this.ucSplitLine_H1 = new HZH_Controls.Controls.UCSplitLine_H();
32             this.lblTitle = new System.Windows.Forms.Label();
33             this.SuspendLayout();
34             // 
35             // ucSplitLine_H1
36             // 
37             this.ucSplitLine_H1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(30)))), ((int)(((byte)(39)))));
38             this.ucSplitLine_H1.Dock = System.Windows.Forms.DockStyle.Bottom;
39             this.ucSplitLine_H1.Location = new System.Drawing.Point(0, 59);
40             this.ucSplitLine_H1.Name = "ucSplitLine_H1";
41             this.ucSplitLine_H1.Size = new System.Drawing.Size(200, 1);
42             this.ucSplitLine_H1.TabIndex = 0;
43             this.ucSplitLine_H1.TabStop = false;
44             // 
45             // lblTitle
46             // 
47             this.lblTitle.Dock = System.Windows.Forms.DockStyle.Fill;
48             this.lblTitle.ForeColor = System.Drawing.Color.White;
49             this.lblTitle.Image = global::HZH_Controls.Properties.Resources.sanjiao2;
50             this.lblTitle.ImageAlign = System.Drawing.ContentAlignment.MiddleRight;
51             this.lblTitle.Location = new System.Drawing.Point(0, 0);
52             this.lblTitle.Name = "lblTitle";
53             this.lblTitle.Size = new System.Drawing.Size(200, 59);
54
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值