C# Winform 自定义 时间线 控件

 

推荐

官网

http://www.hzhcontrols.com/

NetWinform自定义控件

English README.md(github)

English README.md(gitee)

 

根据该控件库重写 https://www.cnblogs.com/bfyx/p/11641874.html

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace 命名空间名称
{
       /// <summary>
    /// Class UCTimeLine.
    /// Implements the <see cref="System.Windows.Forms.UserControl" />
    /// </summary>
    /// <seealso cref="System.Windows.Forms.UserControl" />
    public partial class UCTimeLine : UserControl
    {
        /// <summary>
        /// The line color
        /// </summary>
        private Color lineColor = ColorTranslator.FromHtml("#909399");

        /// <summary>
        /// Gets or sets the color of the line.
        /// </summary>
        /// <value>The color of the line.</value>
        [Description("连接线颜色"), Category("自定义")]
        public Color LineColor
        {
            get { return lineColor; }
            set
            {
                lineColor = value;
                Invalidate();
            }
        }
        /// <summary>
        /// The title font
        /// </summary>
        private Font titleFont = new Font("微软雅黑", 14f);

        /// <summary>
        /// Gets or sets the title font.
        /// </summary>
        /// <value>The title font.</value>
        [Description("标题字体"), Category("自定义")]
        public Font TitleFont
        {
            get { return titleFont; }
            set
            {
                titleFont = value;
                ReloadItems();
            }
        }

        /// <summary>
        /// The title forcolor
        /// </summary>
        private Color titleForcolor = ColorTranslator.FromHtml("#303133");

        /// <summary>
        /// Gets or sets the title forcolor.
        /// </summary>
        /// <value>The title forcolor.</value>
        [Description("标题颜色"), Category("自定义")]
        public Color TitleForcolor
        {
            get { return titleForcolor; }
            set
            {
                titleForcolor = value;
                ReloadItems();
            }
        }

        /// <summary>
        /// The details font
        /// </summary>
        private Font detailsFont = new Font("微软雅黑", 10);

        /// <summary>
        /// Gets or sets the details font.
        /// </summary>
        /// <value>The details font.</value>
        [Description("详情字体"), Category("自定义")]
        public Font DetailsFont
        {
            get { return detailsFont; }
            set
            {
                detailsFont = value;
                ReloadItems();
            }
        }

        /// <summary>
        /// The details forcolor
        /// </summary>
        private Color detailsForcolor = ColorTranslator.FromHtml("#909399");

        /// <summary>
        /// Gets or sets the details forcolor.
        /// </summary>
        /// <value>The details forcolor.</value>
        [Description("详情颜色"), Category("自定义")]
        public Color DetailsForcolor
        {
            get { return detailsForcolor; }
            set
            {
                detailsForcolor = value;
                ReloadItems();
            }
        }

        /// <summary>
        /// The items
        /// </summary>
        TimeLineItem[] items;

        /// <summary>
        /// Gets or sets the items.
        /// </summary>
        /// <value>The items.</value>
        [Description("项列表"), Category("自定义")]
        public TimeLineItem[] Items
        {
            get { return items; }
            set
            {
                items = value;
                ReloadItems();
            }
        }
        public static bool IsDesignMode()
        {
            bool returnFlag = false;

            if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
            {
                returnFlag = true;
            }
            else if (Process.GetCurrentProcess().ProcessName == "devenv")
            {
                returnFlag = true;
            }

            return returnFlag;
        }

        #region 冻结控件
        /// <summary>
        /// The m LST freeze control
        /// </summary>
        static Dictionary<Control, bool> m_lstFreezeControl = new Dictionary<Control, bool>();
        /// <summary>
        /// 功能描述:停止更新控件
        /// 作  者:HZH
        /// 创建日期:2019-07-13 11:11:32
        /// 任务编号:POS
        /// </summary>
        /// <param name="control">control</param>
        /// <param name="blnToFreeze">是否停止更新</param>
        public static void FreezeControl(Control control, bool blnToFreeze)
        {
            if (blnToFreeze && control.IsHandleCreated && control.Visible && !control.IsDisposed && (!m_lstFreezeControl.ContainsKey(control) || (m_lstFreezeControl.ContainsKey(control) && m_lstFreezeControl[control] == false)))
            {
                m_lstFreezeControl[control] = true;
                control.Disposed += control_Disposed;
                SendMessage(control.Handle, 11, 0, 0);
            }
            else if (!blnToFreeze && !control.IsDisposed && m_lstFreezeControl.ContainsKey(control) && m_lstFreezeControl[control] == true)
            {
                m_lstFreezeControl.Remove(control);
                SendMessage(control.Handle, 11, 1, 0);
                control.Invalidate(true);
            }
        }

        /// <summary>
        /// Sends the message.
        /// </summary>
        /// <param name="hWnd">The h WND.</param>
        /// <param name="msg">The MSG.</param>
        /// <param name="wParam">The w parameter.</param>
        /// <param name="lParam">The l parameter.</param>
        [DllImport("user32.dll")]
        public static extern void SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);

        /// <summary>
        /// Handles the Disposed event of the control control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        static void control_Disposed(object sender, EventArgs e)
        {
            try
            {
                if (m_lstFreezeControl.ContainsKey((Control)sender))
                    m_lstFreezeControl.Remove((Control)sender);
            }
            catch { }
        }
        #endregion 冻结控件

        /// <summary>
        /// Initializes a new instance of the <see cref="UCTimeLine"/> class.
        /// </summary>
        public UCTimeLine()
        {
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.DoubleBuffer, true);
            this.SetStyle(ControlStyles.ResizeRedraw, true);
            this.SetStyle(ControlStyles.Selectable, true);
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            this.SetStyle(ControlStyles.UserPaint, true);
            InitializeComponent();
            items = new TimeLineItem[0];
            if (IsDesignMode())
            {
                items = new TimeLineItem[4];
                for (int i = 0; i < 4; i++)
                {
                    items[i] = new TimeLineItem()
                    {
                        Title = DateTime.Now.AddMonths(-1 * (3 - i)).ToString("yyyy年MM月"),
                        Details = DateTime.Now.AddMonths(-1 * (3 - i)).ToString("yyyy年MM月") + "发生了一件大事,咔嚓一声打了一个炸雷,咔嚓一声打了一个炸雷,咔嚓一声打了一个炸雷,咔嚓一声打了一个炸雷,咔嚓一声打了一个炸雷,咔嚓一声打了一个炸雷,咔嚓一声打了一个炸雷,咔嚓一声打了一个炸雷,咔嚓一声打了一个炸雷,然后王二麻子他爹王咔嚓出生了。"
                    };
                }
                ReloadItems();
            }
        }

        /// <summary>
        /// Reloads the items.
        /// </summary>
        private void ReloadItems()
        {
            try
            {
                FreezeControl(this, true);
                this.Controls.Clear();
                if (items != null)
                {
                    foreach (var item in items)
                    {
                        FlowLayoutPanel panelTitle = new FlowLayoutPanel();
                        panelTitle.Dock = DockStyle.Top;
                        panelTitle.AutoScroll = false;
                        panelTitle.Padding = new System.Windows.Forms.Padding(5);
                        panelTitle.Name = "title_" + Guid.NewGuid().ToString();

                        Label lblTitle = new Label();
                        lblTitle.Dock = DockStyle.Top;
                        lblTitle.AutoSize = true;
                        lblTitle.Font = titleFont;
                        lblTitle.ForeColor = titleForcolor;
                        lblTitle.Text = item.Title;
                        lblTitle.SizeChanged += item_SizeChanged;
                        panelTitle.Controls.Add(lblTitle);
                        this.Controls.Add(panelTitle);
                        panelTitle.BringToFront();


                        FlowLayoutPanel panelDetails = new FlowLayoutPanel();
                        panelDetails.Dock = DockStyle.Top;
                        panelDetails.AutoScroll = false;
                        panelDetails.Padding = new System.Windows.Forms.Padding(5);
                        panelDetails.Name = "details_" + Guid.NewGuid().ToString();
                        Label lblDetails = new Label();
                        lblDetails.AutoSize = true;
                        lblDetails.Dock = DockStyle.Top;
                        lblDetails.Font = detailsFont;
                        lblDetails.ForeColor = detailsForcolor;
                        lblDetails.Text = item.Details;
                        lblDetails.SizeChanged += item_SizeChanged;
                        panelDetails.Controls.Add(lblDetails);
                        this.Controls.Add(panelDetails);
                        panelDetails.BringToFront();

                    }
                }
            }
            finally
            {
                FreezeControl(this, false);
            }
        }

        /// <summary>
        /// Handles the SizeChanged event of the item control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        void item_SizeChanged(object sender, EventArgs e)
        {
            Label lbl = (Label)sender;
            lbl.Parent.Height = lbl.Height + 10;
        }

        /// <summary>
        /// 引发 <see cref="E:System.Windows.Forms.Control.Paint" /> 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.PaintEventArgs" />。</param>
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            var g = e.Graphics;
            SetGDIHigh(g);
            var lst = ControlsToArray(Controls).Where(p => p.Name.StartsWith("title_")).ToList();
            for (int i = 0; i < lst.Count; i++)
            {
                //画圆
                g.DrawEllipse(new Pen(new SolidBrush(lineColor)), new Rectangle(7, lst[i].Location.Y + 10, 16, 16));
                //划线
                if (i != lst.Count - 1)
                {
                    g.DrawLine(new Pen(new SolidBrush(lineColor)), new Point(7 + 8, lst[i].Location.Y + 10 - 2), new Point(7 + 8, lst[i + 1].Location.Y + 10 + 16 + 2));
                }
            }
        }

        /// <summary>
        /// 设置GDI高质量模式抗锯齿
        /// </summary>
        /// <param name="g">The g.</param>
        public static void SetGDIHigh(Graphics g)
        {
            g.SmoothingMode = SmoothingMode.AntiAlias;  //使绘图质量最高,即消除锯齿
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.CompositingQuality = CompositingQuality.HighQuality;
        }
        /// <summary>
        /// Converts to array.
        /// </summary>
        /// <param name="controls">The controls.</param>
        /// <returns>Control[].</returns>
        public static Control[] ControlsToArray(System.Windows.Forms.Control.ControlCollection controls)
        {
            if (controls == null || controls.Count <= 0)
                return new Control[0];
            List<Control> lst = new List<Control>();
            foreach (Control item in controls)
            {
                lst.Add(item);
            }
            return lst.ToArray();
        }
    }

    /// <summary>
    /// Class TimeLineItem.
    /// </summary>
    public class TimeLineItem
    {
        /// <summary>
        /// Gets or sets the title.
        /// </summary>
        /// <value>The title.</value>
        public string Title { get; set; }
        /// <summary>
        /// Gets or sets the details.
        /// </summary>
        /// <value>The details.</value>
        public string Details { get; set; }
    } }

 

posted @ 2022-03-13 10:41  LuoCore  阅读(379)  评论(0编辑  收藏  举报