C# - 基于LinkLabel可动态生成多超链接信息的自定义控件

一、效果示意

今天设计了一个自定义控件,用于满足下面的场景:

有一句话,有多个子句组成,每一个子句都要设置对应的超链接。举个例子,比如现有要素:姓名、国籍、生年、卒年。可以组成这么一句话:

“【理查德·尼克松】,国籍【美国】,生于【1913年1月9日】,卒于【1994年4月22日】。”

214208_RZi3_1425762.png

但是,这四个要素并不是每条数据都有的,除了姓名是必须的,后面三点要素都是可选的。比如只有姓名、生年、卒年,没有国籍时,拼成的话就是:

“【霍去病】,生于【前140年】,卒于【前117年】。”

214305_cJ8h_1425762.png

超链接点击后,根据点击的文字,可以触发对应的事件。

214351_1omD_1425762.png

二、控件设计

建立一个继承UserControl类的自定义控件,名为MyLinkLabelPanel,里面有五个Panel,最中间的Panel中添加一个Dock为Fill的LinkLabel。

214801_9BLx_1425762.png

控件代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace LinkLabelTest
{
    /// <summary>
    /// 自制超链接控件
    /// </summary>
    public partial class MyLinkLabelPanel : UserControl
    {
        public MyLinkLabelPanel()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 链接详细信息
        /// </summary>
        private class SituationDetail
        {
            /// <summary>
            /// 链接起始点
            /// </summary>
            public int Start;
            /// <summary>
            /// 链接长度
            /// </summary>
            public int Length;
            /// <summary>
            /// 链接数据
            /// </summary>
            public string Data;
            /// <summary>
            /// 子句内容
            /// </summary>
            public string Description;
            /// <summary>
            /// 链接详细信息
            /// </summary>
            /// <param name="data">链接数据</param>
            /// <param name="description">子句内容</param>
            public SituationDetail(string data, string description)
            {
                this.Data = data;
                this.Description = description;
            }
            /// <summary>
            /// 重载:ToString函数,返回子句内容Description
            /// </summary>
            /// <returns></returns>
            public override string ToString()
            {
                return Description;
            }
        };

        /// <summary>
        /// 根据控件属性设置,生成链接文本
        /// </summary>
        public void RefreshData()
        {
            lnkContent.Text = "";
            lnkContent.Links.Clear();

            LinkedList<SituationDetail> linkedList = new LinkedList<SituationDetail>();
            if (!string.IsNullOrWhiteSpace(Name))
            {
                linkedList.AddLast(new SituationDetail(
                    Name, "【" + Name + "】"));
            }
            else
            {
                lnkContent.Text = "人物姓名不能为空";
                return;
            }
            if (!string.IsNullOrWhiteSpace(Nationality))
            {
                linkedList.AddLast(new SituationDetail(
                    Nationality, "国籍【" + Nationality + "】"));
            }
            if (!string.IsNullOrWhiteSpace(BornDate))
            {
                linkedList.AddLast(new SituationDetail(
                    BornDate, "生于【" + BornDate + "】"));
            }
            if (!string.IsNullOrWhiteSpace(DeadDate))
            {
                linkedList.AddLast(new SituationDetail(
                    DeadDate, "卒于【" + DeadDate + "】"));
            }
            if (linkedList.Count != 0)
            {
                string result = String.Join(",", linkedList) + "。";

                lnkContent.Text = result;
                LinkedListNode<SituationDetail> node = linkedList.First;
                for (int i = 0; i < result.Length; i++)
                {
                    if (result[i] == '【')
                    {
                        node.Value.Start = i;
                    }
                    else if (result[i] == '】')
                    {
                        node.Value.Length = i - node.Value.Start + 1;
                        lnkContent.Links.Add(node.Value.Start, node.Value.Length, node.Value.Data);
                        if (node.Next == null)
                        {
                            break;
                        }
                        else
                        {
                            node = node.Next;
                        }
                    }
                }
            }
            else
            {
                lnkContent.Text = "数据缺失";
            }
        }

        #region 对外开放的可设置属性

        /// <summary>
        /// 姓名
        /// </summary>
        private string _name;

        ///<summary>
        /// 姓名
        ///</summary>
        [System.ComponentModel.Description("姓名")]
        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }

        /// <summary>
        /// 国籍
        /// </summary>
        private string _nationality;

        ///<summary>
        /// 国籍
        ///</summary>
        [System.ComponentModel.Description("国籍")]
        public string Nationality
        {
            get
            {
                return _nationality;
            }
            set
            {
                _nationality = value;
            }
        }

        /// <summary>
        /// 出生日期
        /// </summary>
        private string _bornDate;

        ///<summary>
        /// 出生日期
        ///</summary>
        [System.ComponentModel.Description("出生日期")]
        public string BornDate
        {
            get
            {
                return _bornDate;
            }
            set
            {
                _bornDate = value;
            }
        }

        /// <summary>
        /// 逝世日期
        /// </summary>
        private string _deadDate;

        ///<summary>
        /// 逝世日期
        ///</summary>
        [System.ComponentModel.Description("逝世日期")]
        public string DeadDate
        {
            get
            {
                return _deadDate;
            }
            set
            {
                _deadDate = value;
            }
        }

        #endregion

        /// <summary>
        /// 单击链接时触发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lnkContent_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            lnkContent.Links[lnkContent.Links.IndexOf(e.Link)].Visited = true;
            string selectedItem = e.Link.LinkData.ToString();
            MessageBox.Show("当前点击条目为:" + selectedItem.ToString());
        }
    }
}

注:根据要生成的语句内容,可以灵活将一句话拆分成多个子句。每个子句可以单独写一个属性存放其中的值,将每个子句都存放在类SituationDetail中,在函数RefreshData中将这些子句要素拼成完整的一句话。

三、控件使用

建立一个C#窗体应用程序,主窗体命名为FormMain,放置如下控件:

215604_nsIN_1425762.png

窗体代码如下,这段代码给出了自定义控件MyLinkLabelPanel的使用示例:

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 LinkLabelTest
{
    public partial class FormMain : Form
    {
        public FormMain()
        {
            InitializeComponent();
        }

        private void FormMain_Load(object sender, EventArgs e)
        {
            btnRefreshData_Click(null, null);
        }

        private void btnRefreshData_Click(object sender, EventArgs e)
        {
            //测试数据
            pnlMain.Name = txtName.Text;
            pnlMain.Nationality = txtNationality.Text;
            pnlMain.BornDate = txtBornDate.Text;
            pnlMain.DeadDate = txtDeadDate.Text;

            pnlMain.RefreshData();
        }
    }
}

END

转载于:https://my.oschina.net/Tsybius2014/blog/549291

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值