And*_*att 5 c# treeview .net-2.0 winforms
我有一个子类,System.Windows.Forms.TreeView它手动"绑定"到一组分层数据.我希望用户能够编辑树的标签,并将更改反映回数据.所以我设置LabelEdit为true并覆盖OnAfterLabelEdit到:
protected override void OnAfterLabelEdit(NodeLabelEditEventArgs e)
{
base.OnAfterLabelEdit(e);
TreeNode node = e.Node;
if (PassesSomeValidation(e.Label))
{
MyDataNode dataNode = node.Tag as MyDataNode;
dataNode.SomeBoundValue = e.Label;
int oldIndex = node.Index;
int newIndex = RepositionChangedDataNode(dataNode);
TreeNode parent = node.Parent;
parent.Nodes.RemoveAt(oldIndex);
parent.Nodes.Insert(newIndex, node);
}
else
{
e.CancelEdit = true;
}
}
Run Code Online (Sandbox Code Playgroud)
RepositionChangedDataNode()重新排序数据并返回更改节点在排序后移动到的索引.我希望我可以简单地移动已编辑的节点以反映此移动.
问题是这会导致节点保持编辑模式!我试过调用EndEdit(),在插入节点之前克隆节点,设置LabelEdit为false并返回true,将更改包含在BeginUpdate()/中EndUpdate(),以及这些想法的各种组合,但它们都没有任何效果.
罪魁祸首似乎是插入.即使我尝试插入一个全新的节点,它也会立即进入编辑模式.
那么,有没有办法让TreeView这种方式表现得不那么好?如果没有,是否有一个很好的解决方法?
我考虑过的一些想法:
使用BeginInvoke()推移除嵌件的步骤返回到像这样的消息队列:
BeginInvoke(new MethodInvoker(delegate(
{
parent.Nodes.RemoveAt(oldIndex);
parent.Nodes.Insert(newIndex, node);
}));
Run Code Online (Sandbox Code Playgroud)
对我而言,这比#2更有效,但我知道这可能不是BeginInvoke()打算如何使用,并且可能会产生影响,因为我对消息泵的知识非常有限,无法预测.
如果您使用数据绑定,数据源 (SomeBoundValue) 的更新是否应该触发节点刷新?也许您可以强制货币管理器重新填充树视图...如果您担心性能,您可以使用一种排序算法,该算法可以很好地处理几乎已经排序的数据(例如,不是快速排序 - 合并或堆排序)去提醒)
或者您可以完全放弃数据绑定并手动处理重新定位,因为您已经使用 RepositionChangedDataNode() 完成了一半......
| 归档时间: |
|
| 查看次数: |
2055 次 |
| 最近记录: |