C#下动态加载结点的TreeView控件
来源:互联网 发布:php开发环境安装 编辑:程序博客网 时间:2024/05/22 14:35
我在开发中遇到这么一个问题:如果结点数过多时(近万个),使用TreeView控件加载时速度非常慢。我就想能否做到一开始只加载部分结点,当用户翻页时再加载需要的新结点。但我翻了一个TreeView的资料,没有发现有针对滚动条的事件。于是就自己重载了TreeView控件,添加了对滚动条事件的支持。
添加滚动条事件支持
主要的实现代码很简单,如下所示:
public class MyTreeView : System.Windows.Forms.TreeView
{
private const int WM_VSCROLL = 0x0115; //滚动条事件
private const int WM_MOUSEWHEEL = 0x020A; //鼠标滚轮事件
private const int SB_ENDSCROLL = 8; //滚动结束标志
public event EventHandler VerticalScrolled;
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_VSCROLL || m.Msg == WM_MOUSEWHEEL)
{
if (m.WParam.ToInt32() == SB_ENDSCROLL)
{
VerticalScrolled(this, new EventArgs());
}
}
base.WndProc(ref m);
}
}
{
private const int WM_VSCROLL = 0x0115; //滚动条事件
private const int WM_MOUSEWHEEL = 0x020A; //鼠标滚轮事件
private const int SB_ENDSCROLL = 8; //滚动结束标志
public event EventHandler VerticalScrolled;
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_VSCROLL || m.Msg == WM_MOUSEWHEEL)
{
if (m.WParam.ToInt32() == SB_ENDSCROLL)
{
VerticalScrolled(this, new EventArgs());
}
}
base.WndProc(ref m);
}
}
事件添加好了,现在要做的事情就是动态添加节点了,又出现了一个问题就是,我如何获取当前屏幕区域内的最后一个节点,我使用了如下一个方法获取当前区域内的最后一个树结点:
private TreeNode GetLastNodeInScreen(TreeView tv)
{
TreeNode node = null;
for (int x = tv.ClientSize.Width; x > 0; x -= 5)
{
int y;
for (y = tv.ClientSize.Height; y > 0; y -= 5)
{
node = tv.GetNodeAt(x, y);
if (node != null)
{
break;
}
}
if (y > 0)
break;
}
return node;
}
{
TreeNode node = null;
for (int x = tv.ClientSize.Width; x > 0; x -= 5)
{
int y;
for (y = tv.ClientSize.Height; y > 0; y -= 5)
{
node = tv.GetNodeAt(x, y);
if (node != null)
{
break;
}
}
if (y > 0)
break;
}
return node;
}
动态加载的关键代码如下所示:
private MyTreeView Tree;
/// <summary>
/// 要载入的全部内容
/// </summary>
private List<string> Nodes;
/// <summary>
/// 每次载入的行数
/// </summary>
private const int PageRows = 30;
/// <summary>
/// 总页数
/// </summary>
private int PageCount;
/// <summary>
/// 加载的页数
/// </summary>
private int LoadedPage = 0;
/// <summary>
/// 滚动树内容时触发的事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TreeScrolled(object sender, EventArgs e)
{
if (this.LoadedPage == this.PageCount)
return;
TreeNode last_node_sc = this.GetLastNodeInScreen(this.Tree);
if (this.Tree.Nodes.Count - last_node_sc.Index < 10)
{
this.LoadPage(this.LoadedPage + 1);
}
}
private void Form1_Load(object sender, EventArgs e)
{
this.Tree = new MyTreeView();
this.Tree.Parent = this;
this.Controls.Add(this.Tree);
this.Tree.Top = 10;
this.Tree.Left = 10;
this.Tree.Width = 150;
this.Tree.Height = 200;
this.Tree.VerticalScrolled += new EventHandler(this.TreeScrolled);
this.Nodes = new List<string>();
for (int i = 0; i < 1000; i++)
{
this.Nodes.Add("Node" + i.ToString().PadLeft(4));
}
this.PageCount = (int)Math.Ceiling(Convert.ToDouble(this.Nodes.Count) / PageRows);
this.LoadPage(1);
}
/// <summary>
/// 载入页
/// </summary>
/// <param name="page_no"></param>
private void LoadPage(int page_no)
{
for (int i = this.LoadedPage * PageRows; i < page_no * PageRows - 1 && i < this.Nodes.Count; i++)
{
TreeNode node = new TreeNode();
node.Text = this.Nodes[i];
this.Tree.Nodes.Add(node);
}
this.LoadedPage = page_no;
}
/// <summary>
/// 要载入的全部内容
/// </summary>
private List<string> Nodes;
/// <summary>
/// 每次载入的行数
/// </summary>
private const int PageRows = 30;
/// <summary>
/// 总页数
/// </summary>
private int PageCount;
/// <summary>
/// 加载的页数
/// </summary>
private int LoadedPage = 0;
/// <summary>
/// 滚动树内容时触发的事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TreeScrolled(object sender, EventArgs e)
{
if (this.LoadedPage == this.PageCount)
return;
TreeNode last_node_sc = this.GetLastNodeInScreen(this.Tree);
if (this.Tree.Nodes.Count - last_node_sc.Index < 10)
{
this.LoadPage(this.LoadedPage + 1);
}
}
private void Form1_Load(object sender, EventArgs e)
{
this.Tree = new MyTreeView();
this.Tree.Parent = this;
this.Controls.Add(this.Tree);
this.Tree.Top = 10;
this.Tree.Left = 10;
this.Tree.Width = 150;
this.Tree.Height = 200;
this.Tree.VerticalScrolled += new EventHandler(this.TreeScrolled);
this.Nodes = new List<string>();
for (int i = 0; i < 1000; i++)
{
this.Nodes.Add("Node" + i.ToString().PadLeft(4));
}
this.PageCount = (int)Math.Ceiling(Convert.ToDouble(this.Nodes.Count) / PageRows);
this.LoadPage(1);
}
/// <summary>
/// 载入页
/// </summary>
/// <param name="page_no"></param>
private void LoadPage(int page_no)
{
for (int i = this.LoadedPage * PageRows; i < page_no * PageRows - 1 && i < this.Nodes.Count; i++)
{
TreeNode node = new TreeNode();
node.Text = this.Nodes[i];
this.Tree.Nodes.Add(node);
}
this.LoadedPage = page_no;
}
- C#下动态加载结点的TreeView控件
- silverlight TreeView控件 动态加载
- C#动态绑定treeview控件
- C#动态绑定treeview控件
- C#动态绑定treeview控件
- TreeView控件中结点的自动生成
- TreeView加载结点及结点的删除、内容编辑
- treeview控件的Expand事件下加载数据的控制
- asp.net实现TreeView控件动态增加结点代码
- TreeView 树形控件的加载
- C#中用Treeview控件加载整个硬盘
- C# TreeView控件动态绑定数据库
- C#中控件的动态加载
- C# treeview控件的使用方法
- C# TreeView控件的使用
- Delphi 树形控件(TreeView)结点间的拖动
- TreeView树控件—如何使用TreeView树控件结点前的复选框
- c# 中treeview 树节点图标的动态加载,及选中时图标改变
- 用Socket和MSHTML对象模型创建自己的浏览器
- 不同性质的公司在英文中不同说法
- 使用JavaScript写的操作系统和输入法程序
- 树型控件中目录与子节点检查框同步选择
- 网络程序设计 Sockets
- C#下动态加载结点的TreeView控件
- 自动循环播放的MP3播放器(续)
- 用纯粹的C++编写COM组件
- 轻型数据库SQLite结合PHP的开发
- 自动循环播放的MP3播放器
- 探讨CtreeCtrl::SortChildrenCB
- 使用PHP往Windows系统中添加用户
- 正确使用内存
- Unix程序设计:实现cp命令