Files
lserp_cs_5.0/插件库/Lskj.Main_新疆/Lskj.Main/main2/TreeViewCustom.cs
T
2026-07-10 15:25:05 +08:00

408 lines
15 KiB
C#

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 Lskj.Main.Properties;
using System.Runtime.InteropServices;
namespace Lskj.Main.main2
{
/// <summary>
/// description: 自定义树
/// author: gyc
/// date: 2017-03-16
/// </summary>
public partial class TreeViewCustom : UserControl
{
#region 公有属性
/// <summary>
/// 父节点字段
/// </summary>
public string ParentField;
/// <summary>
/// 显示节点文本字段
/// </summary>
public string TextField;
/// <summary>
/// 父节点关联子节点位数
/// </summary>
public int ParentKeyLength;
public delegate void ButtonClickEventHandler(Button after);
#endregion
#region 私有属性
/// <summary>
/// 上次显示节点
/// </summary>
private string lastTreeNode;
/// <summary>
/// 上次显示按钮ID
/// </summary>
private string lastMenuId;
/// 数据源
/// </summary>
private DataTable dataSource;
private ButtonClickEventHandler clickEvent;
/// <summary>
/// 缓存菜单,按照节点缓存
/// </summary>
private Dictionary<string, List<TreeNodeCustom>> dicTreeNodes = new Dictionary<string, List<TreeNodeCustom>>();
/// <summary>
/// 缓存所有按钮
/// </summary>
private Dictionary<string, Button> dicButtons = new Dictionary<string, Button>();
#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;
/// <summary>
/// 停止界面重绘
/// </summary>
/// <param name="parent"></param>
public static void SuspendDrawing(Control parent)
{
SendMessage(parent.Handle, WM_SETREDRAW, false, 0);
}
/// <summary>
/// 开始绘制
/// </summary>
/// <param name="parent"></param>
public static void ResumeDrawing(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);
}
/// <summary>
/// 注册设置事件
/// </summary>
/// <param name="hoverEvent"></param>
public void SetClickEvent(ButtonClickEventHandler clickEvent)
{
this.clickEvent = clickEvent;
}
/// <summary>
/// 检查是否包含父节点
/// </summary>
/// <returns></returns>
private List<TreeNodeCustom> getParentNodes(string parent)
{
string parentKey = parent.Length == ParentKeyLength ? parent : parent.Substring(0, parent.Length - ParentKeyLength);
List<TreeNodeCustom> treeNodeList = new List<TreeNodeCustom>();
if (dicTreeNodes == null)
dicTreeNodes = new Dictionary<string, List<TreeNodeCustom>>();
if (dicTreeNodes.ContainsKey(parentKey))
{
treeNodeList = dicTreeNodes[parentKey];
}
else
{
dicTreeNodes.Add(parentKey, treeNodeList);
}
return treeNodeList;
}
/// <summary>
/// 加载菜单
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void SetDataSource(DataTable dtTable)
{
int index = 1;
this.dataSource = dtTable;
if (dataSource == null || dataSource.Rows.Count == 0) return;
// 获取根节点
DataRow[] rootRows = dataSource.Rows.Cast<DataRow>().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 = Resources.node_default;
treeNode.btnTreeNode.Font = new Font("微软雅黑", 12);
}
else if (length / ParentKeyLength == 2)
{
treeNode.btnTreeNode.BackgroundImage = Resources.node2_default;
treeNode.btnTreeNode.Padding = new Padding(20, 1, 3, 3);
treeNode.btnTreeNode.Font = new Font("微软雅黑", 11);
}
else
{
treeNode.btnTreeNode.BackgroundImage = 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<TreeNodeCustom> parentNodes = getParentNodes(item[ParentField] + "");
parentNodes.Add(treeNode);
// 隐藏需要放在添加后,否则出现顺序错乱
treeNode.Visible = length == ParentKeyLength;
index++;
}
}
/// <summary>
/// 树节点点击
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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 ? Resources.node_default : Resources.node_select;
}
if (nodeValue.Length == ParentKeyLength * 2)
{
treeNode.btnTreeNode.BackgroundImage = dicTreeNodes[nodeValue][0].Visible ? Resources.node2_default : Resources.node2_select;
}
// 末节点
if (nodeValue.Length == ParentKeyLength * 3)
{
treeNode.btnTreeNode.BackgroundImage = Resources.node3_select;
if (!string.IsNullOrEmpty(lastMenuId) && lastMenuId != treeNode.btnTreeNode.Name)
{
dicButtons[lastMenuId].BackgroundImage = Resources.node3_default;
}
lastMenuId = treeNode.btnTreeNode.Name;
}
List<TreeNodeCustom> treeNodes = new List<TreeNodeCustom>();
// 展开当前点击节点
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 (clickEvent != null)
{
this.clickEvent(treeNode.btnTreeNode);
}
}
lastTreeNode = nodeValue;
}
}
catch (Exception)
{
}
ResumeDrawing(plTreeView);
}
/// <summary>
/// 鼠标移动
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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)
{
// 根节点
//bool isOpen = false;
//List<TreeNodeCustom> nodes = getChildNodes(treeNodeTag);
//foreach (TreeNodeCustom item in nodes)
//{
// if (item.Visible)
// {
// isOpen = true;
// break;
// }
//}
//if (!isOpen)
//{
// button.BackgroundImage = Resources.node_move;
//}
}
else if (treeNodeTag.Length == ParentKeyLength * 2)
{
// 第一级节点
if (dicTreeNodes.ContainsKey(treeNodeTag) && dicTreeNodes[treeNodeTag].Count > 0)
{
button.BackgroundImage = dicTreeNodes[treeNodeTag][0].Visible ? Resources.node2_select : Resources.node2_move;
}
else
{
button.BackgroundImage = Resources.node2_move;
}
}
else
{
// 末节点
if (button.Name != lastMenuId)
{
button.BackgroundImage = Resources.node3_move;
}
}
}
}
catch (Exception ex)
{
}
}
/// <summary>
/// 鼠标离开
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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)
{
// 根节点
//bool isOpen = false;
//List<TreeNodeCustom> nodes = getChildNodes(treeNodeTag);
//foreach (TreeNodeCustom item in nodes)
//{
// if (item.Visible)
// {
// isOpen = true;
// break;
// }
//}
//if (!isOpen)
//{
// button.BackgroundImage = Resources.node_move;
//}
}
else if (treeNodeTag.Length == ParentKeyLength * 2)
{
// 第一级节点
if (dicTreeNodes.ContainsKey(treeNodeTag) && dicTreeNodes[treeNodeTag].Count > 0)
{
button.BackgroundImage = dicTreeNodes[treeNodeTag][0].Visible ? Resources.node2_select : Resources.node2_default;
}
else
{
button.BackgroundImage = Resources.node2_default;
}
}
else
{
// 末节点
if (button.Name != lastMenuId)
{
button.BackgroundImage = Resources.node3_default;
}
}
}
}
catch (Exception ex)
{
}
}
/// <summary>
/// 获取子节点
/// </summary>
/// <returns></returns>
private List<TreeNodeCustom> getChildNodes(string nodeValue)
{
List<TreeNodeCustom> treeNodes = new List<TreeNodeCustom>();
// 获取第3个节点之后的节点
DataRow[] rowChilds = dataSource.Rows.Cast<DataRow>().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<TreeNodeCustom> nodeChilds = dicTreeNodes[item[ParentField] + ""];
foreach (TreeNodeCustom node in nodeChilds)
{
treeNodes.Add(node);
}
}
}
return treeNodes;
}
}
}