/***********************
* 说明:主界面左菜单树
* 创建人:龚宇超
* 创建日期:2018-04-25
* 修改人:
* 修改日期:
* 修改备注:
* 版本:1.0.0.0
***********************/
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;
using System.Runtime.InteropServices;
namespace Lskj.Main.Control
{
public partial class TreeViewCustom : UserControl
{
#region 公有属性
///
/// 父节点字段
///
public string ParentField;
///
/// 显示节点文本字段
///
public string TextField;
///
/// 父节点关联子节点位数
///
public int ParentKeyLength;
///
/// 左侧菜单点击回调
///
/// The after.
public delegate void ButtonClickEventHandler(Button after);
///
/// 左侧菜单事件注册
///
public ButtonClickEventHandler OnButtonClickEvent;
#endregion
#region 私有属性
///
/// 上次显示节点
///
private string _lastTreeNode;
///
/// 上次显示按钮ID
///
private string _lastMenuId;
/// 数据源
///
private DataTable _dataSource;
///
/// 缓存菜单,按照节点缓存
///
private Dictionary> _dicTreeNodes = new Dictionary>();
///
/// 缓存所有按钮
///
private Dictionary _dicButtons = new Dictionary();
#endregion
#region Api
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, Int32 wMsg, bool wParam, Int32 lParam);
private const int WM_SETREDRAW = 11;
///
/// 说明:停止绘制
/// 创建人 龚宇超
/// 创建日期:2018-04-24
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
///
public static void SuspendDrawing(System.Windows.Forms.Control parent)
{
SendMessage(parent.Handle, WM_SETREDRAW, false, 0);
}
///
/// 说明:开始绘制
/// 创建人 龚宇超
/// 创建日期:2018-04-24
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
///
public static void ResumeDrawing(System.Windows.Forms.Control parent)
{
SendMessage(parent.Handle, WM_SETREDRAW, true, 0);
parent.Refresh();
}
#endregion
public TreeViewCustom()
{
InitializeComponent();
}
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0014) return;
base.WndProc(ref m);
}
///
/// 说明:检查是否包含父节点
/// 创建人 龚宇超
/// 创建日期:2018-04-24
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
///
private List getParentNodes(string parent)
{
string parentKey = parent.Length == ParentKeyLength ? parent : parent.Substring(0, parent.Length - ParentKeyLength);
List treeNodeList = new List();
if (_dicTreeNodes == null)
_dicTreeNodes = new Dictionary>();
if (_dicTreeNodes.ContainsKey(parentKey))
{
treeNodeList = _dicTreeNodes[parentKey];
}
else
{
_dicTreeNodes.Add(parentKey, treeNodeList);
}
return treeNodeList;
}
///
/// 说明:加载菜单
/// 创建人 龚宇超
/// 创建日期:2018-04-24
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
public void SetDataSource(DataTable dtTable)
{
int index = 1;
this._dataSource = dtTable;
if (_dataSource == null || _dataSource.Rows.Count == 0) return;
// 获取根节点
DataRow[] rootRows = _dataSource.Rows.Cast().Where(x => (x[ParentField] + "").Length == ParentKeyLength || (x[ParentField] + "").Length == ParentKeyLength * 2).ToArray();
foreach (DataRow item in _dataSource.Rows)
{
int length = (item[ParentField] + "").Length;
TreeNodeCustom treeNode = new TreeNodeCustom();
treeNode.Dock = DockStyle.Top;
treeNode.Tag = item[ParentField] + "";
treeNode.TabIndex = index;
if (length == ParentKeyLength)
{
treeNode.btnTreeNode.BackgroundImage = Lskj.Main.Properties.Resources.node_default;
treeNode.btnTreeNode.Font = new Font("微软雅黑", 12);
}
else if (length / ParentKeyLength == 2)
{
treeNode.btnTreeNode.BackgroundImage = Lskj.Main.Properties.Resources.node2_default;
treeNode.btnTreeNode.Padding = new Padding(20, 1, 3, 3);
treeNode.btnTreeNode.Font = new Font("微软雅黑", 11);
}
else
{
treeNode.btnTreeNode.BackgroundImage = Lskj.Main.Properties.Resources.node3_default;
treeNode.btnTreeNode.Padding = new Padding(30, 1, 3, 3);
treeNode.btnTreeNode.Font = new Font("微软雅黑", 10);
}
treeNode.btnTreeNode.Name = index + "";
treeNode.btnTreeNode.Text = item[TextField] + "";
treeNode.btnTreeNode.Tag = item;
treeNode.btnTreeNode.Click += new EventHandler(btnTreeNode_Click);
treeNode.btnTreeNode.MouseMove += new MouseEventHandler(btnTreeNode_MouseMove);
treeNode.btnTreeNode.MouseLeave += new EventHandler(btnTreeNode_MouseLeave);
plTreeView.Controls.Add(treeNode);
_dicButtons.Add(index + "", treeNode.btnTreeNode);
List parentNodes = getParentNodes(item[ParentField] + "");
parentNodes.Add(treeNode);
// 隐藏需要放在添加后,否则出现顺序错乱
treeNode.Visible = length == ParentKeyLength;
index++;
}
}
///
/// 说明:树点击
/// 创建人 龚宇超
/// 创建日期:2018-04-24
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
private void btnTreeNode_Click(object sender, EventArgs e)
{
try
{
SuspendDrawing(plTreeView);
TreeNodeCustom treeNode = (sender as Button).Parent as TreeNodeCustom;
if (treeNode != null)
{
string nodeValue = treeNode.Tag + "";
if (_lastTreeNode == null)
{
_lastTreeNode = nodeValue;
}
if (nodeValue.Length == ParentKeyLength)
{
treeNode.btnTreeNode.BackgroundImage = _dicTreeNodes[nodeValue][0].Visible ? Lskj.Main.Properties.Resources.node_default : Lskj.Main.Properties.Resources.node_select;
}
if (nodeValue.Length == ParentKeyLength * 2)
{
treeNode.btnTreeNode.BackgroundImage = _dicTreeNodes[nodeValue][0].Visible ? Lskj.Main.Properties.Resources.node2_default : Lskj.Main.Properties.Resources.node2_select;
}
// 末节点
if (nodeValue.Length == ParentKeyLength * 3)
{
treeNode.btnTreeNode.BackgroundImage = Lskj.Main.Properties.Resources.node3_select;
if (!string.IsNullOrEmpty(_lastMenuId) && _lastMenuId != treeNode.btnTreeNode.Name)
{
_dicButtons[_lastMenuId].BackgroundImage = Lskj.Main.Properties.Resources.node3_default;
}
_lastMenuId = treeNode.btnTreeNode.Name;
}
List treeNodes = new List();
// 展开当前点击节点
if (_dicTreeNodes.ContainsKey(nodeValue))
{
treeNodes = _dicTreeNodes[nodeValue];
foreach (TreeNodeCustom node in treeNodes)
{
string menuKey = node.Tag + "";
if (menuKey.Length == ParentKeyLength) continue;
node.Visible = !node.Visible;
Application.DoEvents();// 处理当前消息队列中的所有windows消息
}
}
// 点击根节点隐藏所有子节点
if (nodeValue.Length == ParentKeyLength && !_dicTreeNodes[nodeValue][0].Visible)
{
treeNodes = getChildNodes(nodeValue);
foreach (TreeNodeCustom node in treeNodes)
{
node.Visible = false;
//Application.DoEvents();// 处理当前消息队列中的所有windows消息
}
}
// 点击末节点
if (nodeValue.Length == ParentKeyLength * 3)
{
if (OnButtonClickEvent != null)
{
this.OnButtonClickEvent(treeNode.btnTreeNode);
}
}
_lastTreeNode = nodeValue;
}
}
catch (Exception)
{
}
ResumeDrawing(plTreeView);
}
///
/// 说明:鼠标移动
/// 创建人 龚宇超
/// 创建日期:2018-04-24
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
private void btnTreeNode_MouseMove(object sender, MouseEventArgs e)
{
try
{
Button button = sender as Button;
if (button != null)
{
this.Cursor = Cursors.Hand;
TreeNodeCustom treeNode = button.Parent as TreeNodeCustom;
string treeNodeTag = treeNode.Tag + "";
if (treeNodeTag.Length == ParentKeyLength)
{
}
else if (treeNodeTag.Length == ParentKeyLength * 2)
{
// 第一级节点
if (_dicTreeNodes.ContainsKey(treeNodeTag) && _dicTreeNodes[treeNodeTag].Count > 0)
{
button.BackgroundImage = _dicTreeNodes[treeNodeTag][0].Visible ? Lskj.Main.Properties.Resources.node2_select : Lskj.Main.Properties.Resources.node2_move;
}
else
{
button.BackgroundImage = Lskj.Main.Properties.Resources.node2_move;
}
}
else
{
// 末节点
if (button.Name != _lastMenuId)
{
button.BackgroundImage = Lskj.Main.Properties.Resources.node3_move;
}
}
}
}
catch (Exception ex)
{
}
}
///
/// 说明:鼠标离开
/// 创建人 龚宇超
/// 创建日期:2018-04-24
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
private void btnTreeNode_MouseLeave(object sender, EventArgs e)
{
try
{
Button button = sender as Button;
if (button != null)
{
this.Cursor = Cursors.Hand;
TreeNodeCustom treeNode = button.Parent as TreeNodeCustom;
string treeNodeTag = treeNode.Tag + "";
if (treeNodeTag.Length == ParentKeyLength)
{
}
else if (treeNodeTag.Length == ParentKeyLength * 2)
{
// 第一级节点
if (_dicTreeNodes.ContainsKey(treeNodeTag) && _dicTreeNodes[treeNodeTag].Count > 0)
{
button.BackgroundImage = _dicTreeNodes[treeNodeTag][0].Visible ? Lskj.Main.Properties.Resources.node2_select : Lskj.Main.Properties.Resources.node2_default;
}
else
{
button.BackgroundImage = Lskj.Main.Properties.Resources.node2_default;
}
}
else
{
// 末节点
if (button.Name != _lastMenuId)
{
button.BackgroundImage = Lskj.Main.Properties.Resources.node3_default;
}
}
}
}
catch (Exception ex)
{
}
}
///
/// 说明:获取子节点
/// 创建人 龚宇超
/// 创建日期:2018-04-24
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
///
private List getChildNodes(string nodeValue)
{
List treeNodes = new List();
// 获取第3个节点之后的节点
DataRow[] rowChilds = _dataSource.Rows.Cast().Where(x => (x[ParentField] + "").Length == nodeValue.Length * 2 && (x[ParentField] + "").Substring(0, nodeValue.Length) == nodeValue).ToArray();
foreach (DataRow item in rowChilds)
{
if (_dicTreeNodes.ContainsKey(item[ParentField] + ""))
{
List nodeChilds = _dicTreeNodes[item[ParentField] + ""];
foreach (TreeNodeCustom node in nodeChilds)
{
treeNodes.Add(node);
}
}
}
return treeNodes;
}
}
}