今天设计了一个自定义控件,用于知足下面的场景:node
有一句话,有多个子句组成,每个子句都要设置对应的超连接。举个例子,好比现有要素:姓名、国籍、生年、卒年。能够组成这么一句话:ide
“【理查德·尼克松】,国籍【美国】,生于【1913年1月9日】,卒于【1994年4月22日】。”函数
可是,这四个要素并非每条数据都有的,除了姓名是必须的,后面三点要素都是可选的。好比只有姓名、生年、卒年,没有国籍时,拼成的话就是:测试
“【霍去病】,生于【前140年】,卒于【前117年】。”this
超连接点击后,根据点击的文字,能够触发对应的事件。spa
创建一个继承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
创建一个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