今天設計了一個自定義控件,用於知足下面的場景: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