zoukankan      html  css  js  c++  java
  • (十)c#Winform自定义控件-横向列表-HZHControls

    官网

    http://www.hzhcontrols.com

    前提

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

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

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

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

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

    目录

    https://www.cnblogs.com/bfyx/p/11364884.html

    准备工作

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

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

    开始

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

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

     1 // 版权所有  黄正辉  交流群:568015492   QQ:623128629
     2 // 文件名称:UCHorizontalListItem.cs
     3 // 创建日期:2019-08-15 16:01:13
     4 // 功能描述:HorizontalList
     5 // 项目地址:https://gitee.com/kwwwvagaa/net_winform_custom_control
     6 using System;
     7 using System.Collections.Generic;
     8 using System.ComponentModel;
     9 using System.Drawing;
    10 using System.Data;
    11 using System.Linq;
    12 using System.Text;
    13 using System.Windows.Forms;
    14 
    15 namespace HZH_Controls.Controls
    16 {
    17     [ToolboxItem(false)]
    18     public partial class UCHorizontalListItem : UserControl
    19     {
    20         public event EventHandler SelectedItem;
    21         private KeyValuePair<string, string> _DataSource = new KeyValuePair<string, string>();
    22         public KeyValuePair<string, string> DataSource
    23         {
    24             get { return _DataSource; }
    25             set
    26             {
    27                 _DataSource = value;
    28                 int intWidth = ControlHelper.GetStringWidth(value.Value, lblTitle.CreateGraphics(), lblTitle.Font);
    29                 if (intWidth < 50)
    30                     intWidth = 50;
    31                 this.Width = intWidth + 20;
    32                 lblTitle.Text = value.Value;
    33                 SetSelect(false);
    34             }
    35         }
    36         public UCHorizontalListItem()
    37         {
    38             InitializeComponent();
    39             this.Dock = DockStyle.Right;
    40             this.MouseDown += Item_MouseDown;
    41             this.lblTitle.MouseDown += Item_MouseDown;
    42             this.ucSplitLine_H1.MouseDown += Item_MouseDown;
    43         }
    44 
    45         void Item_MouseDown(object sender, MouseEventArgs e)
    46         {
    47             if (SelectedItem != null)
    48                 SelectedItem(this, e);
    49         }
    50 
    51         public void SetSelect(bool bln)
    52         {
    53             if (bln)
    54             {
    55                 lblTitle.ForeColor = Color.FromArgb(255, 77, 59);
    56                 ucSplitLine_H1.Visible = true;
    57                 this.lblTitle.Padding = new Padding(0, 0, 0, 5);
    58             }
    59             else
    60             {
    61                 lblTitle.ForeColor = Color.FromArgb(64, 64, 64);
    62                 ucSplitLine_H1.Visible = false;
    63                 this.lblTitle.Padding = new Padding(0, 0, 0, 0);
    64             }
    65         }
    66     }
    67 }
    View Code
     1 namespace HZH_Controls.Controls
     2 {
     3     partial class UCHorizontalListItem
     4     {
     5         /// <summary> 
     6         /// 必需的设计器变量。
     7         /// </summary>
     8         private System.ComponentModel.IContainer components = null;
     9 
    10         /// <summary> 
    11         /// 清理所有正在使用的资源。
    12         /// </summary>
    13         /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
    14         protected override void Dispose(bool disposing)
    15         {
    16             if (disposing && (components != null))
    17             {
    18                 components.Dispose();
    19             }
    20             base.Dispose(disposing);
    21         }
    22 
    23         #region 组件设计器生成的代码
    24 
    25         /// <summary> 
    26         /// 设计器支持所需的方法 - 不要
    27         /// 使用代码编辑器修改此方法的内容。
    28         /// </summary>
    29         private void InitializeComponent()
    30         {
    31             this.lblTitle = new System.Windows.Forms.Label();
    32             this.ucSplitLine_H1 = new HZH_Controls.Controls.UCSplitLine_H();
    33             this.SuspendLayout();
    34             // 
    35             // lblTitle
    36             // 
    37             this.lblTitle.Dock = System.Windows.Forms.DockStyle.Fill;
    38             this.lblTitle.Font = new System.Drawing.Font("微软雅黑", 10F);
    39             this.lblTitle.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
    40             this.lblTitle.Location = new System.Drawing.Point(1, 0);
    41             this.lblTitle.Name = "lblTitle";
    42             this.lblTitle.Padding = new System.Windows.Forms.Padding(0, 0, 0, 10);
    43             this.lblTitle.Size = new System.Drawing.Size(118, 50);
    44             this.lblTitle.TabIndex = 1;
    45             this.lblTitle.Text = "分类名称
    分类名称";
    46             this.lblTitle.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
    47             // 
    48             // ucSplitLine_H1
    49             // 
    50             this.ucSplitLine_H1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(77)))), ((int)(((byte)(59)))));
    51             this.ucSplitLine_H1.Dock = System.Windows.Forms.DockStyle.Bottom;
    52             this.ucSplitLine_H1.Location = new System.Drawing.Point(1, 50);
    53             this.ucSplitLine_H1.Name = "ucSplitLine_H1";
    54             this.ucSplitLine_H1.Size = new System.Drawing.Size(118, 3);
    55             this.ucSplitLine_H1.TabIndex = 0;
    56             this.ucSplitLine_H1.TabStop = false;
    57             // 
    58             // UCHorizontalListItem
    59             // 
    60             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
    61             this.Controls.Add(this.lblTitle);
    62             this.Controls.Add(this.ucSplitLine_H1);
    63             this.Name = "UCHorizontalListItem";
    64             this.Padding = new System.Windows.Forms.Padding(1, 0, 1, 0);
    65             this.Size = new System.Drawing.Size(120, 53);
    66             this.ResumeLayout(false);
    67 
    68         }
    69 
    70         #endregion
    71 
    72         private UCSplitLine_H ucSplitLine_H1;
    73         private System.Windows.Forms.Label lblTitle;
    74     }
    75 }
    View Code

    设计效果如图

    接着我们来创建列表控件,添加一个用户控件,命名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();
                }
            }

    我们有时需要刷新列表

     1  public void ReloadSource()
     2         {
     3             try
     4             {
     5                 ControlHelper.FreezeControl(this, true);
     6                 this.panList.SuspendLayout();
     7                 this.panList.Controls.Clear();
     8                 this.panList.Width = this.panMain.Width;
     9                 if (DataSource != null)
    10                 {
    11                     foreach (var item in DataSource)
    12                     {
    13                         UCHorizontalListItem uc = new UCHorizontalListItem();
    14                         uc.DataSource = item;
    15                         uc.SelectedItem += uc_SelectItem;
    16                         this.panList.Controls.Add(uc);
    17                     }
    18                 }
    19                 this.panList.ResumeLayout(true);
    20                 if (this.panList.Controls.Count > 0)
    21                     this.panList.Width = panMain.Width + this.panList.Controls[0].Location.X * -1;
    22                 this.panList.Location = new Point(0, 0);
    23                 m_startItemIndex = 0;
    24                 if (this.panList.Width > panMain.Width)
    25                     panRight.Visible = true;
    26                 else
    27                     panRight.Visible = false;
    28                 panLeft.Visible = false;
    29                 panList.SendToBack();
    30                 panRight.SendToBack();
    31                 if (isAutoSelectFirst && DataSource != null && DataSource.Count > 0)
    32                 {
    33                     SelectItem((UCHorizontalListItem)this.panList.Controls[0]);
    34                 }
    35             }
    36             finally
    37             {
    38                 ControlHelper.FreezeControl(this, false);
    39             }
    40         }

    还需要处理选中处理

    1  private void SelectItem(UCHorizontalListItem item)
    2         {
    3             if (SelectedItem != null && !SelectedItem.IsDisposed)
    4                 SelectedItem.SetSelect(false);
    5             SelectedItem = item;
    6             SelectedItem.SetSelect(true);
    7             if (SelectedItemEvent != null)
    8                 SelectedItemEvent(item, null);
    9         }

    然后就是翻页功能的处理了

     1  private void panLeft_MouseDown(object sender, MouseEventArgs e)
     2         {
     3             if (this.panList.Location.X >= 0)
     4             {
     5                 this.panList.Location = new Point(0, 0);
     6                 return;
     7             }
     8 
     9             for (int i = m_startItemIndex; i >= 0; i--)
    10             {
    11                 if (this.panList.Controls[i].Location.X < this.panList.Controls[m_startItemIndex].Location.X - panMain.Width)
    12                 {
    13                     m_startItemIndex = i + 1;
    14                     break; ;
    15                 }
    16                 if (i == 0)
    17                 {
    18                     m_startItemIndex = 0;
    19                 }
    20             }
    21 
    22             ResetListLocation();
    23             panRight.Visible = true;
    24             if (this.panList.Location.X >= 0)
    25             {
    26                 panLeft.Visible = false;
    27             }
    28             else
    29             {
    30                 panLeft.Visible = true;
    31             }
    32             panList.SendToBack();
    33             panRight.SendToBack();
    34         }
    35 
    36         private void panRight_MouseDown(object sender, MouseEventArgs e)
    37         {
    38             if (this.panList.Location.X + this.panList.Width <= this.panMain.Width)
    39                 return;
    40             if (this.panList.Controls.Count <= 0)
    41                 return;
    42             for (int i = m_startItemIndex; i < this.panList.Controls.Count; i++)
    43             {
    44                 if (this.panList.Location.X + this.panList.Controls[i].Location.X + this.panList.Controls[i].Width > panMain.Width)
    45                 {
    46                     m_startItemIndex = i;
    47                     break;
    48                 }
    49             }
    50             ResetListLocation();
    51             panLeft.Visible = true;
    52             if (panList.Width + panList.Location.X <= panMain.Width)
    53                 panRight.Visible = false;
    54             else
    55                 panRight.Visible = true;
    56             panList.SendToBack();
    57             panRight.SendToBack();
    58         }
    59 
    60         private void ResetListLocation()
    61         {
    62             if (this.panList.Controls.Count > 0)
    63             {
    64                 this.panList.Location = new Point(this.panList.Controls[m_startItemIndex].Location.X * -1, 0);
    65             }
    66         }

    最后向外暴露一个设置选中的功能

     1 public void SetSelect(string strKey)
     2         {
     3             foreach (UCHorizontalListItem item in this.panList.Controls)
     4             {
     5                 if (item.DataSource.Key == strKey)
     6                 {
     7                     SelectItem(item);
     8                     return;
     9                 }
    10             }
    11         }

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

      1 // 版权所有  黄正辉  交流群:568015492   QQ:623128629
      2 // 文件名称:UCHorizontalList.cs
      3 // 创建日期:2019-08-15 16:01:06
      4 // 功能描述:HorizontalList
      5 // 项目地址:https://gitee.com/kwwwvagaa/net_winform_custom_control
      6 using System;
      7 using System.Collections.Generic;
      8 using System.ComponentModel;
      9 using System.Drawing;
     10 using System.Data;
     11 using System.Linq;
     12 using System.Text;
     13 using System.Windows.Forms;
     14 
     15 namespace HZH_Controls.Controls
     16 {
     17     public partial class UCHorizontalList : UserControl
     18     {
     19         public UCHorizontalListItem SelectedItem { get; set; }
     20         public event EventHandler SelectedItemEvent;
     21         private int m_startItemIndex = 0;
     22         private bool isAutoSelectFirst = true;
     23 
     24         public bool IsAutoSelectFirst
     25         {
     26             get { return isAutoSelectFirst; }
     27             set { isAutoSelectFirst = value; }
     28         }
     29 
     30         private List<KeyValuePair<string, string>> dataSource = null;
     31 
     32         public List<KeyValuePair<string, string>> DataSource
     33         {
     34             get { return dataSource; }
     35             set
     36             {
     37                 dataSource = value;
     38                 ReloadSource();
     39             }
     40         }
     41 
     42         public UCHorizontalList()
     43         {
     44             InitializeComponent();
     45         }
     46 
     47         public void ReloadSource()
     48         {
     49             try
     50             {
     51                 ControlHelper.FreezeControl(this, true);
     52                 this.panList.SuspendLayout();
     53                 this.panList.Controls.Clear();
     54                 this.panList.Width = this.panMain.Width;
     55                 if (DataSource != null)
     56                 {
     57                     foreach (var item in DataSource)
     58                     {
     59                         UCHorizontalListItem uc = new UCHorizontalListItem();
     60                         uc.DataSource = item;
     61                         uc.SelectedItem += uc_SelectItem;
     62                         this.panList.Controls.Add(uc);
     63                     }
     64                 }
     65                 this.panList.ResumeLayout(true);
     66                 if (this.panList.Controls.Count > 0)
     67                     this.panList.Width = panMain.Width + this.panList.Controls[0].Location.X * -1;
     68                 this.panList.Location = new Point(0, 0);
     69                 m_startItemIndex = 0;
     70                 if (this.panList.Width > panMain.Width)
     71                     panRight.Visible = true;
     72                 else
     73                     panRight.Visible = false;
     74                 panLeft.Visible = false;
     75                 panList.SendToBack();
     76                 panRight.SendToBack();
     77                 if (isAutoSelectFirst && DataSource != null && DataSource.Count > 0)
     78                 {
     79                     SelectItem((UCHorizontalListItem)this.panList.Controls[0]);
     80                 }
     81             }
     82             finally
     83             {
     84                 ControlHelper.FreezeControl(this, false);
     85             }
     86         }
     87 
     88         void uc_SelectItem(object sender, EventArgs e)
     89         {
     90             SelectItem(sender as UCHorizontalListItem);
     91         }
     92 
     93         private void SelectItem(UCHorizontalListItem item)
     94         {
     95             if (SelectedItem != null && !SelectedItem.IsDisposed)
     96                 SelectedItem.SetSelect(false);
     97             SelectedItem = item;
     98             SelectedItem.SetSelect(true);
     99             if (SelectedItemEvent != null)
    100                 SelectedItemEvent(item, null);
    101         }
    102 
    103         private void panLeft_MouseDown(object sender, MouseEventArgs e)
    104         {
    105             if (this.panList.Location.X >= 0)
    106             {
    107                 this.panList.Location = new Point(0, 0);
    108                 return;
    109             }
    110 
    111             for (int i = m_startItemIndex; i >= 0; i--)
    112             {
    113                 if (this.panList.Controls[i].Location.X < this.panList.Controls[m_startItemIndex].Location.X - panMain.Width)
    114                 {
    115                     m_startItemIndex = i + 1;
    116                     break; ;
    117                 }
    118                 if (i == 0)
    119                 {
    120                     m_startItemIndex = 0;
    121                 }
    122             }
    123 
    124             ResetListLocation();
    125             panRight.Visible = true;
    126             if (this.panList.Location.X >= 0)
    127             {
    128                 panLeft.Visible = false;
    129             }
    130             else
    131             {
    132                 panLeft.Visible = true;
    133             }
    134             panList.SendToBack();
    135             panRight.SendToBack();
    136         }
    137 
    138         private void panRight_MouseDown(object sender, MouseEventArgs e)
    139         {
    140             if (this.panList.Location.X + this.panList.Width <= this.panMain.Width)
    141                 return;
    142             if (this.panList.Controls.Count <= 0)
    143                 return;
    144             for (int i = m_startItemIndex; i < this.panList.Controls.Count; i++)
    145             {
    146                 if (this.panList.Location.X + this.panList.Controls[i].Location.X + this.panList.Controls[i].Width > panMain.Width)
    147                 {
    148                     m_startItemIndex = i;
    149                     break;
    150                 }
    151             }
    152             ResetListLocation();
    153             panLeft.Visible = true;
    154             if (panList.Width + panList.Location.X <= panMain.Width)
    155                 panRight.Visible = false;
    156             else
    157                 panRight.Visible = true;
    158             panList.SendToBack();
    159             panRight.SendToBack();
    160         }
    161 
    162         private void ResetListLocation()
    163         {
    164             if (this.panList.Controls.Count > 0)
    165             {
    166                 this.panList.Location = new Point(this.panList.Controls[m_startItemIndex].Location.X * -1, 0);
    167             }
    168         }
    169 
    170         public void SetSelect(string strKey)
    171         {
    172             foreach (UCHorizontalListItem item in this.panList.Controls)
    173             {
    174                 if (item.DataSource.Key == strKey)
    175                 {
    176                     SelectItem(item);
    177                     return;
    178                 }
    179             }
    180         }
    181     }
    182 }
    View Code
      1 namespace HZH_Controls.Controls
      2 {
      3     partial class UCHorizontalList
      4     {
      5         /// <summary> 
      6         /// 必需的设计器变量。
      7         /// </summary>
      8         private System.ComponentModel.IContainer components = null;
      9 
     10         /// <summary> 
     11         /// 清理所有正在使用的资源。
     12         /// </summary>
     13         /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
     14         protected override void Dispose(bool disposing)
     15         {
     16             if (disposing && (components != null))
     17             {
     18                 components.Dispose();
     19             }
     20             base.Dispose(disposing);
     21         }
     22 
     23         #region 组件设计器生成的代码
     24 
     25         /// <summary> 
     26         /// 设计器支持所需的方法 - 不要
     27         /// 使用代码编辑器修改此方法的内容。
     28         /// </summary>
     29         private void InitializeComponent()
     30         {
     31             this.panMain = new System.Windows.Forms.Panel();
     32             this.panList = new System.Windows.Forms.Panel();
     33             this.panRight = new System.Windows.Forms.Panel();
     34             this.panLeft = new System.Windows.Forms.Panel();
     35             this.panMain.SuspendLayout();
     36             this.SuspendLayout();
     37             // 
     38             // panMain
     39             // 
     40             this.panMain.Controls.Add(this.panList);
     41             this.panMain.Dock = System.Windows.Forms.DockStyle.Fill;
     42             this.panMain.Location = new System.Drawing.Point(46, 0);
     43             this.panMain.Name = "panMain";
     44             this.panMain.Size = new System.Drawing.Size(422, 53);
     45             this.panMain.TabIndex = 3;
     46             // 
     47             // panList
     48             // 
     49             this.panList.Anchor = System.Windows.Forms.AnchorStyles.Left;
     50             this.panList.BackColor = System.Drawing.Color.Transparent;
     51             this.panList.Location = new System.Drawing.Point(0, 0);
     52             this.panList.Name = "panList";
     53             this.panList.Size = new System.Drawing.Size(401, 53);
     54             this.panList.TabIndex = 0;
     55             // 
     56             // panRight
     57             // 
     58             this.panRight.BackgroundImage = global::HZH_Controls.Properties.Resources.chevron_right;
     59             this.panRight.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
     60             this.panRight.Dock = System.Windows.Forms.DockStyle.Right;
     61             this.panRight.Location = new System.Drawing.Point(468, 0);
     62             this.panRight.Name = "panRight";
     63             this.panRight.Size = new System.Drawing.Size(46, 53);
     64             this.panRight.TabIndex = 2;
     65             this.panRight.Visible = false;
     66             this.panRight.MouseDown += new System.Windows.Forms.MouseEventHandler(this.panRight_MouseDown);
     67             // 
     68             // panLeft
     69             // 
     70             this.panLeft.BackgroundImage = global::HZH_Controls.Properties.Resources.chevron_left;
     71             this.panLeft.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
     72             this.panLeft.Dock = System.Windows.Forms.DockStyle.Left;
     73             this.panLeft.Location = new System.Drawing.Point(0, 0);
     74             this.panLeft.Name = "panLeft";
     75             this.panLeft.Size = new System.Drawing.Size(46, 53);
     76             this.panLeft.TabIndex = 1;
     77             this.panLeft.Visible = false;
     78             this.panLeft.MouseDown += new System.Windows.Forms.MouseEventHandler(this.panLeft_MouseDown);
     79             // 
     80             // UCHorizontalList
     81             // 
     82             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
     83             this.Controls.Add(this.panMain);
     84             this.Controls.Add(this.panRight);
     85             this.Controls.Add(this.panLeft);
     86             this.Name = "UCHorizontalList";
     87             this.Size = new System.Drawing.Size(514, 53);
     88             this.panMain.ResumeLayout(false);
     89             this.ResumeLayout(false);
     90 
     91         }
     92 
     93         #endregion
     94 
     95         private System.Windows.Forms.Panel panLeft;
     96         private System.Windows.Forms.Panel panRight;
     97         private System.Windows.Forms.Panel panMain;
     98         private System.Windows.Forms.Panel panList;
     99     }
    100 }
    View Code

    用处及效果

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

    效果:

    调用示例

    1  List<KeyValuePair<string, string>> lstHL = new List<KeyValuePair<string, string>>();
    2             for (int i = 0; i < 30; i++)
    3             {
    4                 lstHL.Add(new KeyValuePair<string, string>(i.ToString(), "选项" + i));
    5             }
    6 
    7             this.ucHorizontalList1.DataSource = lstHL;

    最后的话

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

  • 相关阅读:
    codefoeces problem 671D——贪心+启发式合并+平衡树
    bzoj 1598: [Usaco2008 Mar]牛跑步
    bzoj 1050: [HAOI2006]旅行comf&&【codevs1001】
    codefoeces 671 problem D
    利用FFMPEG以及EasyRTMP实现读取H.264文件推RTMP视频流的两种方式
    视频流拉转推工具对比:EasyRTSPLive和FFMPEG拉转推效果对比
    TSINGSEE青犀视频Webrtc实时通信的构建流程:PeerConnection对等通信的实现方式
    TSINGSEE青犀视频云边端架构产品编译Intel Media SDK 编译报错error"SSE4.1 instruction set not enabled"
    H.265编码视频在web网页实现无插件播放,应该通过软解码还是硬解码?
    【案例分析】EasyDSS+EasyCVR融合共享解决方案
  • 原文地址:https://www.cnblogs.com/bfyx/p/11362517.html
Copyright © 2011-2022 走看看