(十)c#Winform自定义控件-横向列表

前提

入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。

GitHub:https://github.com/kwwwvagaa/NetWinformControl

码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git

如果觉得写的还行,请点个 star 支持一下吧

欢迎前来交流探讨: 企鹅群568015492 企鹅群568015492

目录

https://blog.csdn.net/kwwwvagaa/article/details/100586547

准备工作

梳理一下需求,我们需要一个横向的节点列表控件,可以进行左右翻页

根据上面所写的需求,我们需要分为2步操作,1:创建项控件,2:创建列表控件

开始

首先我们创建项控件,添加一个用户控件,命名UCHorizontalListItem

代码量并不多,我们看下完整代码

// 版权所有  黄正辉  交流群:568015492   QQ:623128629
// 文件名称:UCHorizontalListItem.cs
// 创建日期:2019-08-15 16:01:13
// 功能描述:HorizontalList
// 项目地址: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
    {
        /// <summary> 
        /// 必需的设计器变量。
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary> 
        /// 清理所有正在使用的资源。
        /// </summary>
        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region 组件设计器生成的代码

        /// <summary> 
        /// 设计器支持所需的方法 - 不要
        /// 使用代码编辑器修改此方法的内容。
        /// </summary>
        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 = "分类名称\r\n分类名称";
            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;
    }
}

设计效果如图

 

接着我们来创建列表控件,添加一个用户控件,命名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 List<KeyValuePair<string, string>> dataSource = null;

        public List<KeyValuePair<string, string>> DataSource
        {
            get { return dataSource; }
            set
            {
                dataSource = value;
                ReloadSource();
            }
        }

我们有时需要刷新列表

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 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;
                }
            }
        }

以上就是主要东西了,再看下完整代码

// 版权所有  黄正辉  交流群:568015492   QQ:623128629
// 文件名称:UCHorizontalList.cs
// 创建日期:2019-08-15 16:01:06
// 功能描述:HorizontalList
// 项目地址: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 List<KeyValuePair<string, string>> dataSource = null;

        public List<KeyValuePair<string, 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
    {
        /// <summary> 
        /// 必需的设计器变量。
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary> 
        /// 清理所有正在使用的资源。
        /// </summary>
        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region 组件设计器生成的代码

        /// <summary> 
        /// 设计器支持所需的方法 - 不要
        /// 使用代码编辑器修改此方法的内容。
        /// </summary>
        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;
    }
}

 

用处及效果

用处:一般用着需要横向切换选项的地方,比如省份切换等

效果:

 

调用示例

List<KeyValuePair<string, string>> lstHL = new List<KeyValuePair<string, string>>();
            for (int i = 0; i < 30; i++)
            {
                lstHL.Add(new KeyValuePair<string, string>(i.ToString(), "选项" + i));
            }

            this.ucHorizontalList1.DataSource = lstHL;

最后的话

如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星 星吧

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值