我需要从复合数据库表构建一个巨大的树视图Grouping
.
Grouping
是,我们在SQL Server Management Studio Express中看到的.一个后Database
节点,一些固定的文件夹都显示(如,Database Diagrams
,Tables
,Views
,Synonyms
,Programmability
和Security
)和儿童在这些文件夹中进行分组.
到目前为止,我已经使用AfterSelect
事件和处理程序来实现这一目标.
但问题AfterSelect
是,在选择节点之前,观众无法知道是否有任何可用的孩子.这是因为,可展开的plus
标志不可见.
我想用BeforeExpand
.但问题BeforeExpand
是,如果已经填充了孩子,它就有效.在这种情况下,当我点击组时,没有任何反应.
怎么解决这个?
所以代码/网络链接将不胜感激.
Fre*_*örk 12
我通常做的是在可能存在应该以懒惰方式加载的子项的地方添加"虚拟子节点".这将使父级具有加号,然后您可以将代码添加到AfterExpand事件中,执行以下操作:
我通常给虚拟节点一个文本,如"正在加载数据.请稍候......",以便用户获得有关正在发生的事情的信息.
更新
我把一个简单的例子放在一起:
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; }
}
Run Code Online (Sandbox Code Playgroud)