官网

http://www.hzhcontrols.com

前提

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

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

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

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

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

idkey=6e08741ef16fe53bf0314c1c9e336c4f626047943a8b76bac062361bab6b4f8d">

目录

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

准备工作

对原始树控件treeview进行扩展以更改样式

先了解一下我们需要哪些功能,控件ain可以更改整好颜色,行高,选中效果,分割线等

开始

添加组件,命名TreeViewEx 继承TreeView

先看下属性

  private const int WS_VSCROLL = ;

         private const int GWL_STYLE = -;

         private Dictionary<string, string> _lstTips = new Dictionary<string, string>();

         private Font _tipFont = new Font("Arial Unicode MS", 12f);

         private Image _tipImage = Resources.tips;

         private bool _isShowTip = false;

         private bool _isShowByCustomModel = true;

         private int _nodeHeight = ;

         private Image _nodeDownPic = Resources.list_add;

         private Image _nodeUpPic = Resources.list_subtract;

         private Color _nodeBackgroundColor = Color.FromArgb(, , );

         private Color _nodeForeColor = Color.White;

         private bool _nodeIsShowSplitLine = false;

         private Color _nodeSplitLineColor = Color.FromArgb(, , );

         private Color m_nodeSelectedColor = Color.FromArgb(, , );

         private Color m_nodeSelectedForeColor = Color.White;

         private bool _parentNodeCanSelect = true;

         private SizeF treeFontSize = SizeF.Empty;

         private bool blnHasVBar = false;

         public Dictionary<string, string> LstTips
{
get
{
return this._lstTips;
}
set
{
this._lstTips = value;
}
} [Category("自定义属性"), Description("角标文字字体")]
public Font TipFont
{
get
{
return this._tipFont;
}
set
{
this._tipFont = value;
}
} [Category("自定义属性"), Description("是否显示角标")]
public Image TipImage
{
get
{
return this._tipImage;
}
set
{
this._tipImage = value;
}
} [Category("自定义属性"), Description("是否显示角标")]
public bool IsShowTip
{
get
{
return this._isShowTip;
}
set
{
this._isShowTip = value;
}
} [Category("自定义属性"), Description("使用自定义模式")]
public bool IsShowByCustomModel
{
get
{
return this._isShowByCustomModel;
}
set
{
this._isShowByCustomModel = value;
}
} [Category("自定义属性"), Description("节点高度(IsShowByCustomModel=true时生效)")]
public int NodeHeight
{
get
{
return this._nodeHeight;
}
set
{
this._nodeHeight = value;
base.ItemHeight = value;
}
} [Category("自定义属性"), Description("下翻图标(IsShowByCustomModel=true时生效)")]
public Image NodeDownPic
{
get
{
return this._nodeDownPic;
}
set
{
this._nodeDownPic = value;
}
} [Category("自定义属性"), Description("上翻图标(IsShowByCustomModel=true时生效)")]
public Image NodeUpPic
{
get
{
return this._nodeUpPic;
}
set
{
this._nodeUpPic = value;
}
} [Category("自定义属性"), Description("节点背景颜色(IsShowByCustomModel=true时生效)")]
public Color NodeBackgroundColor
{
get
{
return this._nodeBackgroundColor;
}
set
{
this._nodeBackgroundColor = value;
}
} [Category("自定义属性"), Description("节点字体颜色(IsShowByCustomModel=true时生效)")]
public Color NodeForeColor
{
get
{
return this._nodeForeColor;
}
set
{
this._nodeForeColor = value;
}
} [Category("自定义属性"), Description("节点是否显示分割线(IsShowByCustomModel=true时生效)")]
public bool NodeIsShowSplitLine
{
get
{
return this._nodeIsShowSplitLine;
}
set
{
this._nodeIsShowSplitLine = value;
}
} [Category("自定义属性"), Description("节点分割线颜色(IsShowByCustomModel=true时生效)")]
public Color NodeSplitLineColor
{
get
{
return this._nodeSplitLineColor;
}
set
{
this._nodeSplitLineColor = value;
}
} [Category("自定义属性"), Description("选中节点背景颜色(IsShowByCustomModel=true时生效)")]
public Color NodeSelectedColor
{
get
{
return this.m_nodeSelectedColor;
}
set
{
this.m_nodeSelectedColor = value;
}
} [Category("自定义属性"), Description("选中节点字体颜色(IsShowByCustomModel=true时生效)")]
public Color NodeSelectedForeColor
{
get
{
return this.m_nodeSelectedForeColor;
}
set
{
this.m_nodeSelectedForeColor = value;
}
} [Category("自定义属性"), Description("父节点是否可选中")]
public bool ParentNodeCanSelect
{
get
{
return this._parentNodeCanSelect;
}
set
{
this._parentNodeCanSelect = value;
}
}

样式的更改主要通过节点的重绘,我们使用DrawNode事件来完成

  base.DrawNode += new DrawTreeNodeEventHandler(this.treeview_DrawNode);

 private void treeview_DrawNode(object sender, DrawTreeNodeEventArgs e)
{
try
{
if (e.Node == null || !this._isShowByCustomModel || (e.Node.Bounds.Width <= && e.Node.Bounds.Height <= && e.Node.Bounds.X <= && e.Node.Bounds.Y <= ))
{
e.DrawDefault = true;
}
else
{
if (base.Nodes.IndexOf(e.Node) == )
{
this.blnHasVBar = this.IsVerticalScrollBarVisible();
}
Font font = e.Node.NodeFont;
if (font == null)
{
font = ((TreeView)sender).Font;
}
if (this.treeFontSize == SizeF.Empty)
{
this.treeFontSize = this.GetFontSize(font, e.Graphics);
}
bool flag = false;
int num = ;
if (base.ImageList != null && base.ImageList.Images.Count > && e.Node.ImageIndex >= && e.Node.ImageIndex < base.ImageList.Images.Count)
{
flag = true;
num = (e.Bounds.Height - base.ImageList.ImageSize.Height) / ;
}
if ((e.State == TreeNodeStates.Selected || e.State == TreeNodeStates.Focused || e.State == (TreeNodeStates.Focused | TreeNodeStates.Selected)) && (this._parentNodeCanSelect || e.Node.Nodes.Count <= ))
{
e.Graphics.FillRectangle(new SolidBrush(this.m_nodeSelectedColor), new Rectangle(new Point(, e.Node.Bounds.Y), new Size(base.Width, e.Node.Bounds.Height)));
e.Graphics.DrawString(e.Node.Text, font, new SolidBrush(this.m_nodeSelectedForeColor), (float)e.Bounds.X, (float)e.Bounds.Y + ((float)this._nodeHeight - this.treeFontSize.Height) / 2f);
}
else
{
e.Graphics.FillRectangle(new SolidBrush(this._nodeBackgroundColor), new Rectangle(new Point(, e.Node.Bounds.Y), new Size(base.Width, e.Node.Bounds.Height)));
e.Graphics.DrawString(e.Node.Text, font, new SolidBrush(this._nodeForeColor), (float)e.Bounds.X, (float)e.Bounds.Y + ((float)this._nodeHeight - this.treeFontSize.Height) / 2f);
}
if (flag)
{
int num2 = e.Bounds.X - num - base.ImageList.ImageSize.Width;
if (num2 < )
{
num2 = ;
}
e.Graphics.DrawImage(base.ImageList.Images[e.Node.ImageIndex], new Rectangle(new Point(num2, e.Bounds.Y + num), base.ImageList.ImageSize));
}
if (this._nodeIsShowSplitLine)
{
e.Graphics.DrawLine(new Pen(this._nodeSplitLineColor, 1f), new Point(, e.Bounds.Y + this._nodeHeight - ), new Point(base.Width, e.Bounds.Y + this._nodeHeight - ));
}
bool flag2 = false;
if (e.Node.Nodes.Count > )
{
if (e.Node.IsExpanded && this._nodeUpPic != null)
{
e.Graphics.DrawImage(this._nodeUpPic, new Rectangle(base.Width - (this.blnHasVBar ? : ), e.Bounds.Y + (this._nodeHeight - ) / , , ));
}
else if (this._nodeDownPic != null)
{
e.Graphics.DrawImage(this._nodeDownPic, new Rectangle(base.Width - (this.blnHasVBar ? : ), e.Bounds.Y + (this._nodeHeight - ) / , , ));
}
flag2 = true;
}
if (this._isShowTip && this._lstTips.ContainsKey(e.Node.Name) && !string.IsNullOrWhiteSpace(this._lstTips[e.Node.Name]))
{
int num3 = base.Width - (this.blnHasVBar ? : ) - (flag2 ? : );
int num4 = e.Bounds.Y + (this._nodeHeight - ) / ;
e.Graphics.DrawImage(this._tipImage, new Rectangle(num3, num4, , ));
SizeF sizeF = e.Graphics.MeasureString(this._lstTips[e.Node.Name], this._tipFont, , StringFormat.GenericTypographic);
e.Graphics.DrawString(this._lstTips[e.Node.Name], this._tipFont, new SolidBrush(Color.White), (float)(num3 + ) - sizeF.Width / 2f - 3f, (float)(num4 + ) - sizeF.Height / 2f);
}
}
}
catch (Exception ex)
{
throw ex;
}
} private SizeF GetFontSize(Font font, Graphics g = null)
{
SizeF result;
try
{
bool flag = false;
if (g == null)
{
g = base.CreateGraphics();
flag = true;
}
SizeF sizeF = g.MeasureString("a", font, , StringFormat.GenericTypographic);
if (flag)
{
g.Dispose();
}
result = sizeF;
}
catch (Exception ex)
{
throw ex;
}
return result;
} [DllImport("user32", CharSet = CharSet.Auto)]
private static extern int GetWindowLong(IntPtr hwnd, int nIndex); private bool IsVerticalScrollBarVisible()
{
return base.IsHandleCreated && (TreeViewEx.GetWindowLong(base.Handle, -) & ) != ;
}

我们还需要对选中节点时做一些处理

 private void TreeViewEx_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
try
{
if (e.Node != null)
{
if (e.Node.Nodes.Count > )
{
if (e.Node.IsExpanded)
{
e.Node.Collapse();
}
else
{
e.Node.Expand();
}
}
if (base.SelectedNode != null)
{
if (base.SelectedNode == e.Node && e.Node.IsExpanded)
{
if (!this._parentNodeCanSelect)
{
if (e.Node.Nodes.Count > )
{
base.SelectedNode = e.Node.Nodes[];
}
}
}
}
}
}
catch (Exception ex)
{
throw ex;
}
}

选中后也需要根据属性做相应的操作

  private void TreeViewEx_AfterSelect(object sender, TreeViewEventArgs e)
{
try
{
if (e.Node != null)
{
if (!this._parentNodeCanSelect)
{
if (e.Node.Nodes.Count > )
{
e.Node.Expand();
base.SelectedNode = e.Node.Nodes[];
}
}
}
}
catch (Exception ex)
{
throw ex;
}
}

主要的东西就这些了,我们看下完成的代码吧

 // 版权所有  黄正辉  交流群:568015492   QQ:623128629
// 文件名称:TreeViewEx.cs
// 创建日期:2019-08-15 16:00:55
// 功能描述:TreeView
// 项目地址:https://gitee.com/kwwwvagaa/net_winform_custom_control using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using HZH_Controls.Properties; namespace HZH_Controls.Controls
{
public partial class TreeViewEx : TreeView
{ private const int WS_VSCROLL = ; private const int GWL_STYLE = -; private Dictionary<string, string> _lstTips = new Dictionary<string, string>(); private Font _tipFont = new Font("Arial Unicode MS", 12f); private Image _tipImage = Resources.tips; private bool _isShowTip = false; private bool _isShowByCustomModel = true; private int _nodeHeight = ; private Image _nodeDownPic = Resources.list_add; private Image _nodeUpPic = Resources.list_subtract; private Color _nodeBackgroundColor = Color.FromArgb(, , ); private Color _nodeForeColor = Color.White; private bool _nodeIsShowSplitLine = false; private Color _nodeSplitLineColor = Color.FromArgb(, , ); private Color m_nodeSelectedColor = Color.FromArgb(, , ); private Color m_nodeSelectedForeColor = Color.White; private bool _parentNodeCanSelect = true; private SizeF treeFontSize = SizeF.Empty; private bool blnHasVBar = false; public Dictionary<string, string> LstTips
{
get
{
return this._lstTips;
}
set
{
this._lstTips = value;
}
} [Category("自定义属性"), Description("角标文字字体")]
public Font TipFont
{
get
{
return this._tipFont;
}
set
{
this._tipFont = value;
}
} [Category("自定义属性"), Description("是否显示角标")]
public Image TipImage
{
get
{
return this._tipImage;
}
set
{
this._tipImage = value;
}
} [Category("自定义属性"), Description("是否显示角标")]
public bool IsShowTip
{
get
{
return this._isShowTip;
}
set
{
this._isShowTip = value;
}
} [Category("自定义属性"), Description("使用自定义模式")]
public bool IsShowByCustomModel
{
get
{
return this._isShowByCustomModel;
}
set
{
this._isShowByCustomModel = value;
}
} [Category("自定义属性"), Description("节点高度(IsShowByCustomModel=true时生效)")]
public int NodeHeight
{
get
{
return this._nodeHeight;
}
set
{
this._nodeHeight = value;
base.ItemHeight = value;
}
} [Category("自定义属性"), Description("下翻图标(IsShowByCustomModel=true时生效)")]
public Image NodeDownPic
{
get
{
return this._nodeDownPic;
}
set
{
this._nodeDownPic = value;
}
} [Category("自定义属性"), Description("上翻图标(IsShowByCustomModel=true时生效)")]
public Image NodeUpPic
{
get
{
return this._nodeUpPic;
}
set
{
this._nodeUpPic = value;
}
} [Category("自定义属性"), Description("节点背景颜色(IsShowByCustomModel=true时生效)")]
public Color NodeBackgroundColor
{
get
{
return this._nodeBackgroundColor;
}
set
{
this._nodeBackgroundColor = value;
}
} [Category("自定义属性"), Description("节点字体颜色(IsShowByCustomModel=true时生效)")]
public Color NodeForeColor
{
get
{
return this._nodeForeColor;
}
set
{
this._nodeForeColor = value;
}
} [Category("自定义属性"), Description("节点是否显示分割线(IsShowByCustomModel=true时生效)")]
public bool NodeIsShowSplitLine
{
get
{
return this._nodeIsShowSplitLine;
}
set
{
this._nodeIsShowSplitLine = value;
}
} [Category("自定义属性"), Description("节点分割线颜色(IsShowByCustomModel=true时生效)")]
public Color NodeSplitLineColor
{
get
{
return this._nodeSplitLineColor;
}
set
{
this._nodeSplitLineColor = value;
}
} [Category("自定义属性"), Description("选中节点背景颜色(IsShowByCustomModel=true时生效)")]
public Color NodeSelectedColor
{
get
{
return this.m_nodeSelectedColor;
}
set
{
this.m_nodeSelectedColor = value;
}
} [Category("自定义属性"), Description("选中节点字体颜色(IsShowByCustomModel=true时生效)")]
public Color NodeSelectedForeColor
{
get
{
return this.m_nodeSelectedForeColor;
}
set
{
this.m_nodeSelectedForeColor = value;
}
} [Category("自定义属性"), Description("父节点是否可选中")]
public bool ParentNodeCanSelect
{
get
{
return this._parentNodeCanSelect;
}
set
{
this._parentNodeCanSelect = value;
}
}
public TreeViewEx()
{
base.HideSelection = false;
base.DrawMode = TreeViewDrawMode.OwnerDrawAll;
base.DrawNode += new DrawTreeNodeEventHandler(this.treeview_DrawNode);
base.NodeMouseClick += new TreeNodeMouseClickEventHandler(this.TreeViewEx_NodeMouseClick);
base.SizeChanged += new EventHandler(this.TreeViewEx_SizeChanged);
base.AfterSelect += new TreeViewEventHandler(this.TreeViewEx_AfterSelect);
base.FullRowSelect = true;
base.ShowLines = false;
base.ShowPlusMinus = false;
base.ShowRootLines = false;
this.BackColor = Color.FromArgb(, , );
DoubleBuffered = true;
}
protected override void WndProc(ref Message m)
{ if (m.Msg == 0x0014) // 禁掉清除背景消息WM_ERASEBKGND return; base.WndProc(ref m); }
private void TreeViewEx_AfterSelect(object sender, TreeViewEventArgs e)
{
try
{
if (e.Node != null)
{
if (!this._parentNodeCanSelect)
{
if (e.Node.Nodes.Count > )
{
e.Node.Expand();
base.SelectedNode = e.Node.Nodes[];
}
}
}
}
catch (Exception ex)
{
throw ex;
}
} private void TreeViewEx_SizeChanged(object sender, EventArgs e)
{
this.Refresh();
} private void TreeViewEx_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
try
{
if (e.Node != null)
{
if (e.Node.Nodes.Count > )
{
if (e.Node.IsExpanded)
{
e.Node.Collapse();
}
else
{
e.Node.Expand();
}
}
if (base.SelectedNode != null)
{
if (base.SelectedNode == e.Node && e.Node.IsExpanded)
{
if (!this._parentNodeCanSelect)
{
if (e.Node.Nodes.Count > )
{
base.SelectedNode = e.Node.Nodes[];
}
}
}
}
}
}
catch (Exception ex)
{
throw ex;
}
} private void treeview_DrawNode(object sender, DrawTreeNodeEventArgs e)
{
try
{
if (e.Node == null || !this._isShowByCustomModel || (e.Node.Bounds.Width <= && e.Node.Bounds.Height <= && e.Node.Bounds.X <= && e.Node.Bounds.Y <= ))
{
e.DrawDefault = true;
}
else
{
if (base.Nodes.IndexOf(e.Node) == )
{
this.blnHasVBar = this.IsVerticalScrollBarVisible();
}
Font font = e.Node.NodeFont;
if (font == null)
{
font = ((TreeView)sender).Font;
}
if (this.treeFontSize == SizeF.Empty)
{
this.treeFontSize = this.GetFontSize(font, e.Graphics);
}
bool flag = false;
int num = ;
if (base.ImageList != null && base.ImageList.Images.Count > && e.Node.ImageIndex >= && e.Node.ImageIndex < base.ImageList.Images.Count)
{
flag = true;
num = (e.Bounds.Height - base.ImageList.ImageSize.Height) / ;
}
if ((e.State == TreeNodeStates.Selected || e.State == TreeNodeStates.Focused || e.State == (TreeNodeStates.Focused | TreeNodeStates.Selected)) && (this._parentNodeCanSelect || e.Node.Nodes.Count <= ))
{
e.Graphics.FillRectangle(new SolidBrush(this.m_nodeSelectedColor), new Rectangle(new Point(, e.Node.Bounds.Y), new Size(base.Width, e.Node.Bounds.Height)));
e.Graphics.DrawString(e.Node.Text, font, new SolidBrush(this.m_nodeSelectedForeColor), (float)e.Bounds.X, (float)e.Bounds.Y + ((float)this._nodeHeight - this.treeFontSize.Height) / 2f);
}
else
{
e.Graphics.FillRectangle(new SolidBrush(this._nodeBackgroundColor), new Rectangle(new Point(, e.Node.Bounds.Y), new Size(base.Width, e.Node.Bounds.Height)));
e.Graphics.DrawString(e.Node.Text, font, new SolidBrush(this._nodeForeColor), (float)e.Bounds.X, (float)e.Bounds.Y + ((float)this._nodeHeight - this.treeFontSize.Height) / 2f);
}
if (flag)
{
int num2 = e.Bounds.X - num - base.ImageList.ImageSize.Width;
if (num2 < )
{
num2 = ;
}
e.Graphics.DrawImage(base.ImageList.Images[e.Node.ImageIndex], new Rectangle(new Point(num2, e.Bounds.Y + num), base.ImageList.ImageSize));
}
if (this._nodeIsShowSplitLine)
{
e.Graphics.DrawLine(new Pen(this._nodeSplitLineColor, 1f), new Point(, e.Bounds.Y + this._nodeHeight - ), new Point(base.Width, e.Bounds.Y + this._nodeHeight - ));
}
bool flag2 = false;
if (e.Node.Nodes.Count > )
{
if (e.Node.IsExpanded && this._nodeUpPic != null)
{
e.Graphics.DrawImage(this._nodeUpPic, new Rectangle(base.Width - (this.blnHasVBar ? : ), e.Bounds.Y + (this._nodeHeight - ) / , , ));
}
else if (this._nodeDownPic != null)
{
e.Graphics.DrawImage(this._nodeDownPic, new Rectangle(base.Width - (this.blnHasVBar ? : ), e.Bounds.Y + (this._nodeHeight - ) / , , ));
}
flag2 = true;
}
if (this._isShowTip && this._lstTips.ContainsKey(e.Node.Name) && !string.IsNullOrWhiteSpace(this._lstTips[e.Node.Name]))
{
int num3 = base.Width - (this.blnHasVBar ? : ) - (flag2 ? : );
int num4 = e.Bounds.Y + (this._nodeHeight - ) / ;
e.Graphics.DrawImage(this._tipImage, new Rectangle(num3, num4, , ));
SizeF sizeF = e.Graphics.MeasureString(this._lstTips[e.Node.Name], this._tipFont, , StringFormat.GenericTypographic);
e.Graphics.DrawString(this._lstTips[e.Node.Name], this._tipFont, new SolidBrush(Color.White), (float)(num3 + ) - sizeF.Width / 2f - 3f, (float)(num4 + ) - sizeF.Height / 2f);
}
}
}
catch (Exception ex)
{
throw ex;
}
} private SizeF GetFontSize(Font font, Graphics g = null)
{
SizeF result;
try
{
bool flag = false;
if (g == null)
{
g = base.CreateGraphics();
flag = true;
}
SizeF sizeF = g.MeasureString("a", font, , StringFormat.GenericTypographic);
if (flag)
{
g.Dispose();
}
result = sizeF;
}
catch (Exception ex)
{
throw ex;
}
return result;
} [DllImport("user32", CharSet = CharSet.Auto)]
private static extern int GetWindowLong(IntPtr hwnd, int nIndex); private bool IsVerticalScrollBarVisible()
{
return base.IsHandleCreated && (TreeViewEx.GetWindowLong(base.Handle, -) & ) != ;
}
}
}

用处及效果

用处:觉得原始的treeview太难看了,想换一种好看点的风格

效果:

调用示例

 for (int i = ; i < ; i++)
{
TreeNode tn = new TreeNode(" 父节点" + i);
for (int j = ; j < ; j++)
{
tn.Nodes.Add(" 子节点" + j);
}
this.treeViewEx1.Nodes.Add(tn);
}

最后的话

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

(九)c#Winform自定义控件-树的更多相关文章

  1. (四十七)c#Winform自定义控件-树表格(treeGrid)

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...

  2. (四十九)c#Winform自定义控件-下拉框(表格)

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...

  3. c#Winform自定义控件-目录

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  4. winform 自定义控件(高手)

    高手推荐:https://www.cnblogs.com/bfyx/p/11364884.html   c#Winform自定义控件-目录   前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件 ...

  5. (七十九)c#Winform自定义控件-导航菜单

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...

  6. (八十九)c#Winform自定义控件-自定义滚动条(treeview、panel、datagridview、listbox、listview、textbox)

    官网 http://www.hzhcontrols.com/ 前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kw ...

  7. (六十九)c#Winform自定义控件-垂直滚动条

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...

  8. (三十)c#Winform自定义控件-文本框(三)

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  9. (三十一)c#Winform自定义控件-文本框(四)

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

随机推荐

  1. Java项目案例之--封装的实例

    Java项目案例之---封装的实例 有一个专业类,有一个专业对象,专业名称:计算机科学与技术,专业编号:J001,专业年限:4,对年限添加约束,如果输入小于0,则默认为0,否则显示输入的值 有一个学生 ...

  2. 判断List中是否含有某个实体bean

    注意:使用List.contains(Object object)方法判断ArrayList是否包含一个元素对象(针对于对象的属性值相同,但对象地址不同的情况),如果没有重写List的元素对象Obje ...

  3. 无法在<fastCGI>应用程序配置中找到<handler> scriptProcessor

    在打开php文件的时候发现iis7.5报错了 每次在切换php版本的时候不知道为什么会出现这个错误,有的时候就又不会报错直接可以正常使用,然而php版本确定已经下载好,才可能的打开这个页面,那么就是i ...

  4. Spring Boot 2.x (十八):邮件服务一文打尽

    前景介绍 在日常的工作中,我们经常会用到邮件服务,比如发送验证码,找回密码确认,注册时邮件验证等,所以今天在这里进行邮件服务的一些操作. 大致思路 我们要做的其实就是把Java程序作为一个客户端,然后 ...

  5. 附录:1-Grain生命周期-译注

    Grain Lifecycle Grains are logical entities that always exist, virtually, and have stable logical id ...

  6. seleniumGrid分布式远程执行测试脚本

    执行UI自动化测试脚本时,不仅可以在本地执行,也可以远程指定某计算机执行测试脚本,seleniumGrid为我们提供了这类服务,但还需要自己搭建环境. 一.本地计算机需要准备java环境和seleni ...

  7. poi解析excel文件报错

    getFileMagic() only operates on streams which support mark(int) 使用 bis 解决 BufferedInputStream bis = ...

  8. Hive的架构原理&Hive的安装步骤

    Hive架构图 元数据默认数据库是:Derby.开发使用MySQL Hive如何将SQL语句翻译成MapReduce的? 1.使用SQL解析器解析SQL语句 2.使用编译器进行编译逻辑 3.使用优化器 ...

  9. 2019牛客多校第二场H-Second Large Rectangle

    Second Large Rectangle 题目传送门 解题思路 先求出每个点上的高,再利用单调栈分别求出每个点左右两边第一个高小于自己的位置,从而而得出最后一个大于等于自己的位置,进而求出自己的位 ...

  10. hdu6395 Sequence(分段矩阵快速幂)

    Sequence 题目传送门 解题思路 可以比较容易的推出矩阵方程,但是由于p/i向下取整的值在变,所以要根据p/i的变化将矩阵分段快速幂.p/i一共有sqrt(p)种结果,所以最多可以分为sqrt( ...