using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CustomTreeView.Properties;
namespace GADPlatSystem.Tools
{
/// <summary>
/// 自定义TreeView控件,支持节点级别的复选、单选;
/// 节点显示样式改为Icon+CheckBox+NodeText的样式
/// </summary>
public class GTreeView : TreeView
{
#region Private Variables
private const int checkBoxImageWidth = 16;
private const int checkBoxImageHeight = 16;
private Image imgChecked;
private Image imgUnchecked;
private Image imgRBChecked;
private Image imgRBUnchecked;
private System.ComponentModel.IContainer components;
#endregion
#region Constructs
public GTreeView()
{
InitializeComponent();
// 初始化CheckBox相关的图片
imgUnchecked = Resource.TreeNodeUnchecked;
imgChecked = Resource.TreeNodeChecked;
imgRBUnchecked = Resource.TreeNodeRBUnchecked;
imgRBChecked = Resource.TreeNodeRBChecked;
// 设置TreeView为自己绘制文本和图标并绑定相关的事件
this.DrawMode = TreeViewDrawMode.OwnerDrawText;
this.DrawNode += new DrawTreeNodeEventHandler(GTreeView_DrawNode);
this.MouseUp += new MouseEventHandler(GTreeView_MouseUp);
}
#endregion
#region Event Hanlder Methods
/// <summary>
/// 判断如果点击的是Checkbox图片,则改变节点的IsCheck属性值
/// 需要注意的是同一父节点下只允许一个RadioButton类型的节点为选中状态
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void GTreeView_MouseUp(object sender, MouseEventArgs e)
{
GTreeNode node = GetNodeAt(e.X, e.Y) as GTreeNode;
if (node == null || !node.CheckBoxVisible)
{
return;
}
Rectangle checkboxImgRect = new Rectangle(node.Bounds.X, node.Bounds.Y, checkBoxImageWidth, checkBoxImageHeight); //节点区域
// 如果点击的是checkbox图片
if (checkboxImgRect.Contains(e.X, e.Y))
{
node.Checked = !node.Checked;
// 如果是单选,则设置同级别的其它单选项为unchecked.
if (node.Parent != null && node.CheckBoxStyle == GTreeNode.CheckBoxStyleEnum.RadioButton)
{
foreach (TreeNode siblingNode in node.Parent.Nodes)
{
var siblingGNode = siblingNode as GTreeNode;
if (siblingGNode == null)
{
continue;
}
if (siblingGNode.Name != node.Name && siblingGNode.CheckBoxStyle == GTreeNode.CheckBoxStyleEnum.RadioButton && siblingGNode.Checked)
{
siblingGNode.Checked = false;
}
}
}
}
}
/// <summary>
/// 绘制节点的图标和文字,样式为Icon+CheckBox+NodeText
/// Checkbox支持节点级别的单选、复选
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void GTreeView_DrawNode(object sender, DrawTreeNodeEventArgs e)
{
GTreeNode node = e.Node as GTreeNode;
if (node == null)
{
return;
}
Rectangle nodeRect = e.Node.Bounds;
// 如果需要显示CheckBox,则绘制
if (node.CheckBoxVisible)
{
Point drawPt = new Point(nodeRect.Location.X, nodeRect.Location.Y); //绘制图标的起始位置
Size imgSize = new Size(checkBoxImageWidth, checkBoxImageHeight); //图片大小
Rectangle imgRect = new Rectangle(drawPt, imgSize);
if (e.Node.Checked)
{
if (node.CheckBoxStyle == GTreeNode.CheckBoxStyleEnum.CheckBox)
{
e.Graphics.DrawImage(imgChecked, imgRect);
}
else
{
e.Graphics.DrawImage(imgRBChecked, imgRect);
}
}
else
{
if (node.CheckBoxStyle == GTreeNode.CheckBoxStyleEnum.CheckBox)
{
e.Graphics.DrawImage(imgUnchecked, imgRect);
}
else
{
e.Graphics.DrawImage(imgRBUnchecked, imgRect);
}
}
}
//-----------------------绘制文本 -------------------------------
Rectangle textRec;
if (node.CheckBoxVisible)
{
textRec = new Rectangle(nodeRect.X + checkBoxImageWidth + 2, nodeRect.Y, nodeRect.Width, nodeRect.Height);
}
else
{
textRec = nodeRect;
}
Font nodeFont = e.Node.NodeFont;
if (nodeFont == null)
nodeFont = ((TreeView)sender).Font;
Brush textBrush = SystemBrushes.WindowText;
if ((e.State & TreeNodeStates.Focused) != 0)
{
e.Graphics.FillRectangle(SystemBrushes.Highlight, textRec);
}
e.Graphics.DrawString(e.Node.Text, nodeFont, textBrush, Rectangle.Inflate(textRec, 2, 0));
}
/// <summary>
/// 节点被选中后,如果节点有事件处理程序,则调用
/// </summary>
/// <param name="e"></param>
protected override void OnAfterSelect(TreeViewEventArgs e)
{
var gNode = e.Node as GTreeNode;
if (gNode != null && gNode.NodeSelected != null)
{
TreeViewEventArgs arg = new TreeViewEventArgs(e.Node);
gNode.NodeSelected(this, arg);
return;
}
base.OnAfterSelect(e);
}
#endregion
#region Private Methods
private void InitializeComponent()
{
this.SuspendLayout();
//
// GTreeView
//
this.LineColor = System.Drawing.Color.Black;
this.ResumeLayout(false);
}
#endregion
}
}