C# - 基於LinkLabel可動態生成多超連接信息的自定義控件

1、效果示意

今天設計了一個自定義控件,用於知足下面的場景:node

有一句話,有多個子句組成,每個子句都要設置對應的超連接。舉個例子,好比現有要素:姓名、國籍、生年、卒年。能夠組成這麼一句話:ide

「【理查德·尼克松】,國籍【美國】,生於【1913年1月9日】,卒於【1994年4月22日】。」函數

可是,這四個要素並非每條數據都有的,除了姓名是必須的,後面三點要素都是可選的。好比只有姓名、生年、卒年,沒有國籍時,拼成的話就是:測試

「【霍去病】,生於【前140年】,卒於【前117年】。」this

超連接點擊後,根據點擊的文字,能夠觸發對應的事件。spa

2、控件設計

創建一個繼承UserControl類的自定義控件,名爲MyLinkLabelPanel,裏面有五個Panel,最中間的Panel中添加一個Dock爲Fill的LinkLabel。設計

控件代碼以下:code

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中將這些子句要素拼成完整的一句話。orm

3、控件使用

創建一個C#窗體應用程序,主窗體命名爲FormMain,放置以下控件:繼承

窗體代碼以下,這段代碼給出了自定義控件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

相關文章
相關標籤/搜索