TreeView的子节点填充问题 [英] TreeView child node populating problem
问题描述
我需要构建从复合数据库表中一个巨大的树形与分组
。
I need to construct a huge treeview from a composite database table with Grouping
.
分组
是的,我们在SQL Server Management Studio Express的看到。一个数据库
节点后,一些固定的文件夹都显示(如,数据库图表
,表
,查看
,同义词
,可编程
和安全
)和孩子在这些文件夹中进行分组。
Grouping
is, what we see in SQL Server Management Studio Express. After a Database
node, some fixed folders are shown (like, Database Diagrams
, Tables
, Views
, Synonyms
, Programmability
and Security
) and children are grouped in those folders.
到现在为止我已经使用 AfterSelect
事件处理程序来实现这一目标。
Up to this point I have used AfterSelect
event and handler to achieve this.
但随着 AfterSelect
是,在选择节点之前,观看者无法知道是否有任何可用的孩子。这是因为,可扩展的 加</ code>
登录是不可见的。
But the problem with AfterSelect
is, before selecting the node, the viewer is not able to know whether there is any child available. This is because, the expandable plus
sign is not visible.
我要使用 BeforeExpand
。但随着 BeforeExpand
的问题是,它的工作原理,如果已填充的孩子们。在这种情况下,当我点击组,没有任何反应。
I want to use BeforeExpand
. But the problem with BeforeExpand
is, it works if the children are already populated. In that case, when I click groups, nothing happens.
如何解决此问题?
因此码/网络链接将不胜感激。
So codes/web-link will be appreciated.
推荐答案
我最常做的是增加一个虚拟子节点只要有可能应该在一个懒惰的方式加载孩子。这将使父有加号,然后就可以到你做以下的AfterExpand事件中添加代码:
What I usually do is to add a "dummy child node" wherever there may be children that should be loaded in a lazy manner. This will make the parent have the plus sign, and then you can add code to the AfterExpand event where you do the following:
- 检查有有只有一个孩子,如果孩子是虚拟节点(可以使用Tag属性来确定虚拟节点)
- 如果发现虚拟节点,发动搜索得到孩子,并将其添加到父节点,通过删除虚拟节点完成它。
我通常给虚拟节点如文本正在加载数据,请稍候......左右,从而使用户得到上正在发生的事情的一些信息。
I typically give the dummy node a text like "Loading data. Please wait..." or so, so that the user gets some info on what is going on.
更新结果
我把一个简单的例子:
Update
I put together a simple example:
public class TreeViewSample : Form
{
private TreeView _treeView;
public TreeViewSample()
{
this._treeView = new System.Windows.Forms.TreeView();
this._treeView.Location = new System.Drawing.Point(12, 12);
this._treeView.Size = new System.Drawing.Size(200, 400);
this._treeView.AfterExpand +=
new TreeViewEventHandler(TreeView_AfterExpand);
this.ClientSize = new System.Drawing.Size(224, 424);
this.Controls.Add(this._treeView);
this.Text = "TreeView Lazy Load Sample";
InitializeTreeView();
}
void TreeView_AfterExpand(object sender, TreeViewEventArgs e)
{
if (e.Node.Nodes.Count == 1 && e.Node.Nodes[0].Tag == "dummy")
{
// this node has not yet been populated, launch a thread
// to get the data
ThreadPool.QueueUserWorkItem(state =>
{
IEnumerable<SomeClass> childItems = GetData();
// load the data into the tree view (on the UI thread)
_treeView.BeginInvoke((Action)delegate
{
PopulateChildren(e.Node, childItems);
});
});
}
}
private void PopulateChildren(TreeNode parent, IEnumerable<SomeClass> childItems)
{
TreeNode child;
TreeNode dummy;
TreeNode originalDummyItem = parent.Nodes[0];
foreach (var item in childItems)
{
child = new TreeNode(item.Text);
dummy = new TreeNode("Loading. Please wait...");
dummy.Tag = "dummy";
child.Nodes.Add(dummy);
parent.Nodes.Add(child);
}
originalDummyItem.Remove();
}
private IEnumerable<SomeClass> GetData()
{
// simulate that this takes some time
Thread.Sleep(500);
return new List<SomeClass>
{
new SomeClass{Text = "One"},
new SomeClass{Text = "Two"},
new SomeClass{Text = "Three"}
};
}
private void InitializeTreeView()
{
TreeNode rootNode = new TreeNode("Root");
TreeNode dummyNode = new TreeNode("Loading. Please wait...");
dummyNode.Tag = "dummy";
rootNode.Nodes.Add(dummyNode);
_treeView.Nodes.Add(rootNode);
}
}
public class SomeClass
{
public string Text { get; set; }
}
这篇关于TreeView的子节点填充问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!