请问SQL Server Management Studio 2005 中,打开树节点时边加载边显示(Expanding...)的效果是如何实现的?

awenjie 2008-05-29 10:37:43
请问SQL Server Management Studio 2005 中,打开树节点时边加载边显示(Expanding...)的效果是如何实现的?

这种效果在加载大量的数据到树节点时,避免让用户苦等,挺酷的。请问如何实现呢?

有代码示例最好了!
...全文
133 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
awenjie 2008-05-30
  • 打赏
  • 举报
回复
这时我的代码,使用了BackGroundWorker组件来后台加载。使用了两个Delegate分别用来更改TreeNode的Text和增加树节点。

另外扩展了TreeNode,增加了Opened属性,用来判断是否已经打开过!



public partial class Form1 : Form
{
class TreeNodeEx : TreeNode
{
public TreeNodeEx(string text)
: base(text)
{
}

//用来控制节点是否已经打开过
private bool opened = false;
public bool Opened
{
get { return opened; }
set { opened = value; }
}
}

//添加节点的代理
private delegate void AddNodeDelegate(TreeNode root, string childText);
private AddNodeDelegate myAddNode = null;

//修改节点名称的代理
private delegate void AlterTreeNodeText(string text);
private AlterTreeNodeText alterTreeNodeText = null;

//当前选择的节点
TreeNodeEx currentSelectedNode = null;
string oldValue;

public Form1()
{
InitializeComponent();
TreeNodeEx n = new TreeNodeEx("1");
n.
this.treeView1.Nodes.Add(new TreeNodeEx("1"));
this.treeView1.Nodes.Add(new TreeNodeEx("2"));

alterTreeNodeText = new AlterTreeNodeText(this.OnAlterTreeNodeText);
myAddNode = new AddNodeDelegate(this.AddNodes);
}

protected void OnAlterTreeNodeText(string text)
{
if (currentSelectedNode != null)
currentSelectedNode.Text = text;
}
private void AddNodes(TreeNode node, string text)
{
node.Expand();
node.Nodes.Add(new TreeNodeEx(text));
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
TreeNodeEx node = e.Argument as TreeNodeEx;
if (node == null) return;

oldValue = node.Text;
string newValue = string.Concat(oldValue, "(Expanding...)");
BeginInvoke(alterTreeNodeText, new object[] { newValue });

for (int i = 1; i <= 50; i++)
{
IAsyncResult ar = BeginInvoke(myAddNode, new object[] { node, i.ToString() });
// 等待添加完毕
while (!ar.IsCompleted)
{
Thread.Sleep(100);
Application.DoEvents();
ar.AsyncWaitHandle.WaitOne(-1, false);
}
}
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
BeginInvoke(alterTreeNodeText, new object[] { oldValue });
currentSelectedNode.Opened = true;
}

private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
{
currentSelectedNode = e.Node as TreeNodeEx;
if (currentSelectedNode.Opened) return;
this.backgroundWorker1.RunWorkerAsync(currentSelectedNode);
}
}

hanjoe109 2008-05-29
  • 打赏
  • 举报
回复
隨便說說

能不能選擇樹節點後直接把節點值加上Expanding...,等到展開後再修改回來

awenjie 2008-05-29
  • 打赏
  • 举报
回复
顶一下!
virusswb 2008-05-29
  • 打赏
  • 举报
回复
就是多线程异步执行,用委托传回结果
jinjazz 2008-05-29
  • 打赏
  • 举报
回复
下面代码演示,单击节点后,在5秒钟后添加子节点
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication11
{
public partial class Form1 : Form
{
public class ThreadStartInfo
{
public TreeNode node=null;
public void LoadNode()
{
System.Threading.Thread.Sleep(5000);
string[] str = new string[] { "jinjazz", "csdn" };
this.AddNode(node, str);
}
delegate void dAddNode(TreeNode node, string[] str);
void AddNode(TreeNode node, string[] str)
{
if (this.node.TreeView.FindForm().InvokeRequired)
{
this.node.TreeView.FindForm().Invoke(new dAddNode(AddNode), new object[] { node, str });
}
else
{
node.Nodes.Clear();
foreach (string strNode in str)
{
node.Nodes.Add(strNode);
}
}

}
}

public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
this.treeView1.Nodes.Add(new TreeNode("root"));
this.treeView1.AfterSelect += new TreeViewEventHandler(treeView1_AfterSelect);
}

void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
if (e.Node.Tag==null||e.Node.Tag.ToString() == "")
{
ThreadStartInfo s = new ThreadStartInfo();
s.node = e.Node;
s.node.Tag = 1;
new System.Threading.Thread(new System.Threading.ThreadStart(s.LoadNode)).Start();
e.Node.Nodes.Add("正在载入..");
}
}




}
}
awenjie 2008-05-29
  • 打赏
  • 举报
回复
Scorpico 的方案是一种很好的替代方案。在显示新的窗体的同时,增加大量的节点! 这种方式弹出了新的窗体,用户感受不是很好! 而且,和我要的不是一种方法!不是我要的方案。十分感谢!
awenjie 2008-05-29
  • 打赏
  • 举报
回复
TO(amandag) 是Winform的程序
Scorpico 2008-05-29
  • 打赏
  • 举报
回复
有个类似的方法,LZ可以参考一下
新建一个窗体frmStatus,放置一个Label,Dock属性为Fill,在后台添加一函数ShowMessage
public partial class frmStatus : Form
{
public frmStatus()
{
InitializeComponent();
}

public void ShowMessage(string message)
{
this.lbMsg.Text = message;
this.ShowIcon = false;
this.Show();
Application.DoEvents();
}
}
然后再展开树节点时,调用该函数
private void treeExplorer_AfterSelect(object sender, TreeViewEventArgs e)
{
try
{
frmStatus frm = new frmStatus();
frm.ShowMessage("文件读取中,请稍后...");
//展开树节点时的代码
//......
//代码结束
frm.Close();
}
catch//(Exception ex)
{
// MessageBox.Show(ex.Message);
}
}
此处只是在展开节点时显示文字效果,要想实现其他效果,在frmStatus中放置其他控件.
amandag 2008-05-29
  • 打赏
  • 举报
回复
要看你是在winform中做还是在webform中做
awenjie 2008-05-29
  • 打赏
  • 举报
回复
一般的TreeNode都是加载节点后,然后再展开的。咱们看来,是直接展开,没有一个动态的增加节点的过程。

如果如 hanjoe109 所说的话,效果会不太一样,而且,判断合适展开完毕也是个问题,有时候用户并没有选择节点,而是只点击了+号。

我任务微软应该是扩展了TreeNode节点,在其中增加了多线程的处理过程。遍历数据,有一个加一个,动态的加载。但具体如何实现,一头迷雾!

111,120

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧