(十)c#Winform自定義控件-橫向列表
準(zhǔn)備工作
梳理一下需求,我們需要一個(gè)橫向的節(jié)點(diǎn)列表控件,可以進(jìn)行左右翻頁(yè)
根據(jù)上面所寫(xiě)的需求,我們需要分為2步操作,1:創(chuàng)建項(xiàng)控件,2:創(chuàng)建列表控件
開(kāi)始
首先我們創(chuàng)建項(xiàng)控件,添加一個(gè)用戶(hù)控件,命名UCHorizontalListItem
代碼量并不多,我們看下完整代碼
//?版權(quán)所有??黃正輝??交流群:568015492 ? QQ:623128629
//?文件名稱(chēng):UCHorizontalListItem.cs
//?創(chuàng)建日期:2019-08-15 16:01:13
//?功能描述:HorizontalList
//?項(xiàng)目地址:https://gitee.com/kwwwvagaa/net_winform_custom_control
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?HZH_Controls.Controls
{
????[ToolboxItem(false)]
????public?partial?class?UCHorizontalListItem?:?UserControl
????{
????????public?event?EventHandler?SelectedItem;
????????private?KeyValuePair<string,?string>?_DataSource?=?new?KeyValuePair<string,?string>();
????????public?KeyValuePair<string,?string>?DataSource
????????{
????????????get?{?return?_DataSource;?}
????????????set
????????????{
????????????????_DataSource?=?value;
????????????????int?intWidth?=?ControlHelper.GetStringWidth(value.Value,?lblTitle.CreateGraphics(),?lblTitle.Font);
????????????????if?(intWidth?50)
????????????????????intWidth?=?50;
????????????????this.Width?=?intWidth?+?20;
????????????????lblTitle.Text?=?value.Value;
????????????????SetSelect(false);
????????????}
????????}
????????public?UCHorizontalListItem()
????????{
????????????InitializeComponent();
????????????this.Dock?=?DockStyle.Right;
????????????this.MouseDown?+=?Item_MouseDown;
????????????this.lblTitle.MouseDown?+=?Item_MouseDown;
????????????this.ucSplitLine_H1.MouseDown?+=?Item_MouseDown;
????????}
????????void?Item_MouseDown(object?sender,?MouseEventArgs?e)
????????{
????????????if?(SelectedItem?!=?null)
????????????????SelectedItem(this,?e);
????????}
????????public?void?SetSelect(bool?bln)
????????{
????????????if?(bln)
????????????{
????????????????lblTitle.ForeColor?=?Color.FromArgb(255,?77,?59);
????????????????ucSplitLine_H1.Visible?=?true;
????????????????this.lblTitle.Padding?=?new?Padding(0,?0,?0,?5);
????????????}
????????????else
????????????{
????????????????lblTitle.ForeColor?=?Color.FromArgb(64,?64,?64);
????????????????ucSplitLine_H1.Visible?=?false;
????????????????this.lblTitle.Padding?=?new?Padding(0,?0,?0,?0);
????????????}
????????}
????}
}
namespace?HZH_Controls.Controls
{
????partial?class?UCHorizontalListItem
????{
????????///? ?
????????///?必需的設(shè)計(jì)器變量。
????????///?
????????private?System.ComponentModel.IContainer?components?=?null;
????????///? ?
????????///?清理所有正在使用的資源。
????????///?
????????///?如果應(yīng)釋放托管資源,為 true;否則為 false。
????????protected?override?void?Dispose(bool?disposing)
????????{
????????????if?(disposing?&&?(components?!=?null))
????????????{
????????????????components.Dispose();
????????????}
????????????base.Dispose(disposing);
????????}
????????#region?組件設(shè)計(jì)器生成的代碼
????????///? ?
????????///?設(shè)計(jì)器支持所需的方法?-?不要
????????///?使用代碼編輯器修改此方法的內(nèi)容。
????????///?
????????private?void?InitializeComponent()
????????{
????????????this.lblTitle?=?new?System.Windows.Forms.Label();
????????????this.ucSplitLine_H1?=?new?HZH_Controls.Controls.UCSplitLine_H();
????????????this.SuspendLayout();
????????????//?
????????????//?lblTitle
????????????//?
????????????this.lblTitle.Dock?=?System.Windows.Forms.DockStyle.Fill;
????????????this.lblTitle.Font?=?new?System.Drawing.Font("微軟雅黑",?10F);
????????????this.lblTitle.ForeColor?=?System.Drawing.Color.FromArgb(((int)(((byte)(64)))),?((int)(((byte)(64)))),?((int)(((byte)(64)))));
????????????this.lblTitle.Location?=?new?System.Drawing.Point(1,?0);
????????????this.lblTitle.Name?=?"lblTitle";
????????????this.lblTitle.Padding?=?new?System.Windows.Forms.Padding(0,?0,?0,?10);
????????????this.lblTitle.Size?=?new?System.Drawing.Size(118,?50);
????????????this.lblTitle.TabIndex?=?1;
????????????this.lblTitle.Text?=?"分類(lèi)名稱(chēng)rn分類(lèi)名稱(chēng)";
????????????this.lblTitle.TextAlign?=?System.Drawing.ContentAlignment.MiddleCenter;
????????????//?
????????????//?ucSplitLine_H1
????????????//?
????????????this.ucSplitLine_H1.BackColor?=?System.Drawing.Color.FromArgb(((int)(((byte)(255)))),?((int)(((byte)(77)))),?((int)(((byte)(59)))));
????????????this.ucSplitLine_H1.Dock?=?System.Windows.Forms.DockStyle.Bottom;
????????????this.ucSplitLine_H1.Location?=?new?System.Drawing.Point(1,?50);
????????????this.ucSplitLine_H1.Name?=?"ucSplitLine_H1";
????????????this.ucSplitLine_H1.Size?=?new?System.Drawing.Size(118,?3);
????????????this.ucSplitLine_H1.TabIndex?=?0;
????????????this.ucSplitLine_H1.TabStop?=?false;
????????????//?
????????????//?UCHorizontalListItem
????????????//?
????????????this.AutoScaleMode?=?System.Windows.Forms.AutoScaleMode.None;
????????????this.Controls.Add(this.lblTitle);
????????????this.Controls.Add(this.ucSplitLine_H1);
????????????this.Name?=?"UCHorizontalListItem";
????????????this.Padding?=?new?System.Windows.Forms.Padding(1,?0,?1,?0);
????????????this.Size?=?new?System.Drawing.Size(120,?53);
????????????this.ResumeLayout(false);
????????}
????????#endregion
????????private?UCSplitLine_H?ucSplitLine_H1;
????????private?System.Windows.Forms.Label?lblTitle;
????}
}
設(shè)計(jì)效果如圖

接著我們來(lái)創(chuàng)建列表控件,添加一個(gè)用戶(hù)控件,命名UCHorizontalList
我們看下需要提供哪些屬性
public?UCHorizontalListItem?SelectedItem?{?get;?set;?}
public?event?EventHandler?SelectedItemEvent;
private?int?m_startItemIndex?=?0;
private?bool?isAutoSelectFirst?=?true;
public?bool?IsAutoSelectFirst
{
????get?{?return?isAutoSelectFirst;?}
????set?{?isAutoSelectFirst?=?value;?}
}
private?Liststring,?string>>?dataSource?=?null;
public?Liststring,?string>>?DataSource
{
????get?{?return?dataSource;?}
????set
????{
????????dataSource?=?value;
????????ReloadSource();
????}
}
我們有時(shí)需要刷新列表
public?void?ReloadSource()
{
????try
????{
????????ControlHelper.FreezeControl(this,?true);
????????this.panList.SuspendLayout();
????????this.panList.Controls.Clear();
????????this.panList.Width?=?this.panMain.Width;
????????if?(DataSource?!=?null)
????????{
????????????foreach?(var?item?in?DataSource)
????????????{
????????????????UCHorizontalListItem?uc?=?new?UCHorizontalListItem();
????????????????uc.DataSource?=?item;
????????????????uc.SelectedItem?+=?uc_SelectItem;
????????????????this.panList.Controls.Add(uc);
????????????}
????????}
????????this.panList.ResumeLayout(true);
????????if?(this.panList.Controls.Count?>?0)
????????????this.panList.Width?=?panMain.Width?+?this.panList.Controls[0].Location.X?*?-1;
????????this.panList.Location?=?new?Point(0,?0);
????????m_startItemIndex?=?0;
????????if?(this.panList.Width?>?panMain.Width)
????????????panRight.Visible?=?true;
????????else
????????????panRight.Visible?=?false;
????????panLeft.Visible?=?false;
????????panList.SendToBack();
????????panRight.SendToBack();
????????if?(isAutoSelectFirst?&&?DataSource?!=?null?&&?DataSource.Count?>?0)
????????{
????????????SelectItem((UCHorizontalListItem)this.panList.Controls[0]);
????????}
????}
????finally
????{
????????ControlHelper.FreezeControl(this,?false);
????}
}
還需要處理選中處理
private?void?SelectItem(UCHorizontalListItem?item)
{
????if?(SelectedItem?!=?null?&&?!SelectedItem.IsDisposed)
????????SelectedItem.SetSelect(false);
????SelectedItem?=?item;
????SelectedItem.SetSelect(true);
????if?(SelectedItemEvent?!=?null)
????????SelectedItemEvent(item,?null);
}private?void?SelectItem(UCHorizontalListItem?item)
{
????if?(SelectedItem?!=?null?&&?!SelectedItem.IsDisposed)
????????SelectedItem.SetSelect(false);
????SelectedItem?=?item;
????SelectedItem.SetSelect(true);
????if?(SelectedItemEvent?!=?null)
????????SelectedItemEvent(item,?null);
}
然后就是翻頁(yè)功能的處理了
private?void?panLeft_MouseDown(object?sender,?MouseEventArgs?e)
{
???if?(this.panList.Location.X?>=?0)
???{
???????this.panList.Location?=?new?Point(0,?0);
???????return;
???}
???for?(int?i?=?m_startItemIndex;?i?>=?0;?i--)
???{
???????if?(this.panList.Controls[i].Location.X?this.panList.Controls[m_startItemIndex].Location.X?-?panMain.Width)
???????{
???????????m_startItemIndex?=?i?+?1;
???????????break;?;
???????}
???????if?(i?==?0)
???????{
???????????m_startItemIndex?=?0;
???????}
???}
???ResetListLocation();
???panRight.Visible?=?true;
???if?(this.panList.Location.X?>=?0)
???{
???????panLeft.Visible?=?false;
???}
???else
???{
???????panLeft.Visible?=?true;
???}
???panList.SendToBack();
???panRight.SendToBack();
}
private?void?panRight_MouseDown(object?sender,?MouseEventArgs?e)
{
???if?(this.panList.Location.X?+?this.panList.Width?<=?this.panMain.Width)
???????return;
???if?(this.panList.Controls.Count?<=?0)
???????return;
???for?(int?i?=?m_startItemIndex;?i?this.panList.Controls.Count;?i++)
???{
???????if?(this.panList.Location.X?+?this.panList.Controls[i].Location.X?+?this.panList.Controls[i].Width?>?panMain.Width)
???????{
???????????m_startItemIndex?=?i;
???????????break;
???????}
???}
???ResetListLocation();
???panLeft.Visible?=?true;
???if?(panList.Width?+?panList.Location.X?<=?panMain.Width)
???????panRight.Visible?=?false;
???else
???????panRight.Visible?=?true;
???panList.SendToBack();
???panRight.SendToBack();
}
private?void?ResetListLocation()
{
???if?(this.panList.Controls.Count?>?0)
???{
???????this.panList.Location?=?new?Point(this.panList.Controls[m_startItemIndex].Location.X?*?-1,?0);
???}
}
最后向外暴露一個(gè)設(shè)置選中的功能
public?void?SetSelect(string?strKey)
{
??foreach?(UCHorizontalListItem?item?in?this.panList.Controls)
??{
??????if?(item.DataSource.Key?==?strKey)
??????{
??????????SelectItem(item);
??????????return;
??????}
??}
}
以上就是主要東西了,再看下完整代碼
//?版權(quán)所有??黃正輝??交流群:568015492 ? QQ:623128629
//?文件名稱(chēng):UCHorizontalList.cs
//?創(chuàng)建日期:2019-08-15 16:01:06
//?功能描述:HorizontalList
//?項(xiàng)目地址:https://gitee.com/kwwwvagaa/net_winform_custom_control
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?HZH_Controls.Controls
{
????public?partial?class?UCHorizontalList?:?UserControl
????{
????????public?UCHorizontalListItem?SelectedItem?{?get;?set;?}
????????public?event?EventHandler?SelectedItemEvent;
????????private?int?m_startItemIndex?=?0;
????????private?bool?isAutoSelectFirst?=?true;
????????public?bool?IsAutoSelectFirst
????????{
????????????get?{?return?isAutoSelectFirst;?}
????????????set?{?isAutoSelectFirst?=?value;?}
????????}
????????private?Liststring,?string>>?dataSource?=?null;
????????public?Liststring,?string>>?DataSource
????????{
????????????get?{?return?dataSource;?}
????????????set
????????????{
????????????????dataSource?=?value;
????????????????ReloadSource();
????????????}
????????}
????????public?UCHorizontalList()
????????{
????????????InitializeComponent();
????????}
????????public?void?ReloadSource()
????????{
????????????try
????????????{
????????????????ControlHelper.FreezeControl(this,?true);
????????????????this.panList.SuspendLayout();
????????????????this.panList.Controls.Clear();
????????????????this.panList.Width?=?this.panMain.Width;
????????????????if?(DataSource?!=?null)
????????????????{
????????????????????foreach?(var?item?in?DataSource)
????????????????????{
????????????????????????UCHorizontalListItem?uc?=?new?UCHorizontalListItem();
????????????????????????uc.DataSource?=?item;
????????????????????????uc.SelectedItem?+=?uc_SelectItem;
????????????????????????this.panList.Controls.Add(uc);
????????????????????}
????????????????}
????????????????this.panList.ResumeLayout(true);
????????????????if?(this.panList.Controls.Count?>?0)
????????????????????this.panList.Width?=?panMain.Width?+?this.panList.Controls[0].Location.X?*?-1;
????????????????this.panList.Location?=?new?Point(0,?0);
????????????????m_startItemIndex?=?0;
????????????????if?(this.panList.Width?>?panMain.Width)
????????????????????panRight.Visible?=?true;
????????????????else
????????????????????panRight.Visible?=?false;
????????????????panLeft.Visible?=?false;
????????????????panList.SendToBack();
????????????????panRight.SendToBack();
????????????????if?(isAutoSelectFirst?&&?DataSource?!=?null?&&?DataSource.Count?>?0)
????????????????{
????????????????????SelectItem((UCHorizontalListItem)this.panList.Controls[0]);
????????????????}
????????????}
????????????finally
????????????{
????????????????ControlHelper.FreezeControl(this,?false);
????????????}
????????}
????????void?uc_SelectItem(object?sender,?EventArgs?e)
????????{
????????????SelectItem(sender?as?UCHorizontalListItem);
????????}
????????private?void?SelectItem(UCHorizontalListItem?item)
????????{
????????????if?(SelectedItem?!=?null?&&?!SelectedItem.IsDisposed)
????????????????SelectedItem.SetSelect(false);
????????????SelectedItem?=?item;
????????????SelectedItem.SetSelect(true);
????????????if?(SelectedItemEvent?!=?null)
????????????????SelectedItemEvent(item,?null);
????????}
????????private?void?panLeft_MouseDown(object?sender,?MouseEventArgs?e)
????????{
????????????if?(this.panList.Location.X?>=?0)
????????????{
????????????????this.panList.Location?=?new?Point(0,?0);
????????????????return;
????????????}
????????????for?(int?i?=?m_startItemIndex;?i?>=?0;?i--)
????????????{
????????????????if?(this.panList.Controls[i].Location.X?this.panList.Controls[m_startItemIndex].Location.X?-?panMain.Width)
????????????????{
????????????????????m_startItemIndex?=?i?+?1;
????????????????????break;?;
????????????????}
????????????????if?(i?==?0)
????????????????{
????????????????????m_startItemIndex?=?0;
????????????????}
????????????}
????????????ResetListLocation();
????????????panRight.Visible?=?true;
????????????if?(this.panList.Location.X?>=?0)
????????????{
????????????????panLeft.Visible?=?false;
????????????}
????????????else
????????????{
????????????????panLeft.Visible?=?true;
????????????}
????????????panList.SendToBack();
????????????panRight.SendToBack();
????????}
????????private?void?panRight_MouseDown(object?sender,?MouseEventArgs?e)
????????{
????????????if?(this.panList.Location.X?+?this.panList.Width?<=?this.panMain.Width)
????????????????return;
????????????if?(this.panList.Controls.Count?<=?0)
????????????????return;
????????????for?(int?i?=?m_startItemIndex;?i?this.panList.Controls.Count;?i++)
????????????{
????????????????if?(this.panList.Location.X?+?this.panList.Controls[i].Location.X?+?this.panList.Controls[i].Width?>?panMain.Width)
????????????????{
????????????????????m_startItemIndex?=?i;
????????????????????break;
????????????????}
????????????}
????????????ResetListLocation();
????????????panLeft.Visible?=?true;
????????????if?(panList.Width?+?panList.Location.X?<=?panMain.Width)
????????????????panRight.Visible?=?false;
????????????else
????????????????panRight.Visible?=?true;
????????????panList.SendToBack();
????????????panRight.SendToBack();
????????}
????????private?void?ResetListLocation()
????????{
????????????if?(this.panList.Controls.Count?>?0)
????????????{
????????????????this.panList.Location?=?new?Point(this.panList.Controls[m_startItemIndex].Location.X?*?-1,?0);
????????????}
????????}
????????public?void?SetSelect(string?strKey)
????????{
????????????foreach?(UCHorizontalListItem?item?in?this.panList.Controls)
????????????{
????????????????if?(item.DataSource.Key?==?strKey)
????????????????{
????????????????????SelectItem(item);
????????????????????return;
????????????????}
????????????}
????????}
????}
}
namespace?HZH_Controls.Controls
{
????partial?class?UCHorizontalList
????{
????????///? ?
????????///?必需的設(shè)計(jì)器變量。
????????///?
????????private?System.ComponentModel.IContainer?components?=?null;
????????///? ?
????????///?清理所有正在使用的資源。
????????///?
????????///?如果應(yīng)釋放托管資源,為 true;否則為 false。
????????protected?override?void?Dispose(bool?disposing)
????????{
????????????if?(disposing?&&?(components?!=?null))
????????????{
????????????????components.Dispose();
????????????}
????????????base.Dispose(disposing);
????????}
????????#region?組件設(shè)計(jì)器生成的代碼
????????///? ?
????????///?設(shè)計(jì)器支持所需的方法?-?不要
????????///?使用代碼編輯器修改此方法的內(nèi)容。
????????///?
????????private?void?InitializeComponent()
????????{
????????????this.panMain?=?new?System.Windows.Forms.Panel();
????????????this.panList?=?new?System.Windows.Forms.Panel();
????????????this.panRight?=?new?System.Windows.Forms.Panel();
????????????this.panLeft?=?new?System.Windows.Forms.Panel();
????????????this.panMain.SuspendLayout();
????????????this.SuspendLayout();
????????????//?
????????????//?panMain
????????????//?
????????????this.panMain.Controls.Add(this.panList);
????????????this.panMain.Dock?=?System.Windows.Forms.DockStyle.Fill;
????????????this.panMain.Location?=?new?System.Drawing.Point(46,?0);
????????????this.panMain.Name?=?"panMain";
????????????this.panMain.Size?=?new?System.Drawing.Size(422,?53);
????????????this.panMain.TabIndex?=?3;
????????????//?
????????????//?panList
????????????//?
????????????this.panList.Anchor?=?System.Windows.Forms.AnchorStyles.Left;
????????????this.panList.BackColor?=?System.Drawing.Color.Transparent;
????????????this.panList.Location?=?new?System.Drawing.Point(0,?0);
????????????this.panList.Name?=?"panList";
????????????this.panList.Size?=?new?System.Drawing.Size(401,?53);
????????????this.panList.TabIndex?=?0;
????????????//?
????????????//?panRight
????????????//?
????????????this.panRight.BackgroundImage?=?global::HZH_Controls.Properties.Resources.chevron_right;
????????????this.panRight.BackgroundImageLayout?=?System.Windows.Forms.ImageLayout.Center;
????????????this.panRight.Dock?=?System.Windows.Forms.DockStyle.Right;
????????????this.panRight.Location?=?new?System.Drawing.Point(468,?0);
????????????this.panRight.Name?=?"panRight";
????????????this.panRight.Size?=?new?System.Drawing.Size(46,?53);
????????????this.panRight.TabIndex?=?2;
????????????this.panRight.Visible?=?false;
????????????this.panRight.MouseDown?+=?new?System.Windows.Forms.MouseEventHandler(this.panRight_MouseDown);
????????????//?
????????????//?panLeft
????????????//?
????????????this.panLeft.BackgroundImage?=?global::HZH_Controls.Properties.Resources.chevron_left;
????????????this.panLeft.BackgroundImageLayout?=?System.Windows.Forms.ImageLayout.Center;
????????????this.panLeft.Dock?=?System.Windows.Forms.DockStyle.Left;
????????????this.panLeft.Location?=?new?System.Drawing.Point(0,?0);
????????????this.panLeft.Name?=?"panLeft";
????????????this.panLeft.Size?=?new?System.Drawing.Size(46,?53);
????????????this.panLeft.TabIndex?=?1;
????????????this.panLeft.Visible?=?false;
????????????this.panLeft.MouseDown?+=?new?System.Windows.Forms.MouseEventHandler(this.panLeft_MouseDown);
????????????//?
????????????//?UCHorizontalList
????????????//?
????????????this.AutoScaleMode?=?System.Windows.Forms.AutoScaleMode.None;
????????????this.Controls.Add(this.panMain);
????????????this.Controls.Add(this.panRight);
????????????this.Controls.Add(this.panLeft);
????????????this.Name?=?"UCHorizontalList";
????????????this.Size?=?new?System.Drawing.Size(514,?53);
????????????this.panMain.ResumeLayout(false);
????????????this.ResumeLayout(false);
????????}
????????#endregion
????????private?System.Windows.Forms.Panel?panLeft;
????????private?System.Windows.Forms.Panel?panRight;
????????private?System.Windows.Forms.Panel?panMain;
????????private?System.Windows.Forms.Panel?panList;
????}
}
用處及效果
用處:一般用著需要橫向切換選項(xiàng)的地方,比如省份切換等
效果:

調(diào)用示例
Liststring,?string>>?lstHL?=?new?Liststring,?string>>();
for?(int?i?=?0;?i?30;?i++)
{
????lstHL.Add(new?KeyValuePair<string,?string>(i.ToString(),?"選項(xiàng)"?+?i));
}
this.ucHorizontalList1.DataSource?=?lstHL;
最后的話
如果你喜歡的話,請(qǐng)到 https://gitee.com/kwwwvagaa/net_winform_custom_control 點(diǎn)個(gè)星星吧,另本站轉(zhuǎn)載地址:https://dotnet9.com/5323.html。
作者:冰封一夏 出處:http://www.hzhcontrols.com/doc.html 本文版權(quán)歸作者所有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明, 且在文章頁(yè)面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。 GitHub:https://github.com/kwwwvagaa/NetWinformControl 碼云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
評(píng)論
圖片
表情
