C# WinForms MultiSelectTreeView-EnsureRevible()不工作
删除一个TreeNode后,我希望视图位于删除的TreeNode之后的节点上(稍后还应实现编辑节点的相同功能),但当前它总是再次显示列表的顶部,我需要手动向下滚动,这可能会让用户非常恼火 我使用的是EnsureRevisible()方法,但不幸的是它不起作用(我正在用一个树视图测试它,它包含大约30个没有子节点的节点) 函数的代码(我认为只有第一行和最后4/5行相关):C# WinForms MultiSelectTreeView-EnsureRevible()不工作,c#,winforms,treeview,C#,Winforms,Treeview,删除一个TreeNode后,我希望视图位于删除的TreeNode之后的节点上(稍后还应实现编辑节点的相同功能),但当前它总是再次显示列表的顶部,我需要手动向下滚动,这可能会让用户非常恼火 我使用的是EnsureRevisible()方法,但不幸的是它不起作用(我正在用一个树视图测试它,它包含大约30个没有子节点的节点) 函数的代码(我认为只有第一行和最后4/5行相关): public override void Remove() { TreeNode moveToThisNode=treeCon
public override void Remove()
{
TreeNode moveToThisNode=treeControl1.SelectedNodes.Last().NextVisibleNode;
//首先,根据它们是对象组还是对象类型对它们进行分组
变量分组=来自treeControl1.SelectedNodes中的节点
其中!node.IsUngroupedNode()
让isGroup=node.IsGroupNode()
按isGroup将节点分组为g
选择new{IsGroupNode=g.Key,Items=g};
foreach(分组中的var grp)
{
foreach(grp.Items中的变量selectedNode)
{
//仅允许首先删除对象组,然后删除不是“未分组”组的对象组。
if(grp.IsGroupNode)
{
//删除组
var cmd=(Commands.DataCommand)mApplicationData.CommandFactory.Create(string.Concat(CommandPrefix,“Remove”);
cmd.Data=selectedNode.Text;
cmd.Execute();
}
else//ObjectType节点-->只需移动到“取消分组”
{
var t=(ObjectType)selectedNode.Tag;
var parentNode=selectedNode.Parent;
if(parentNode?.IsGroupNode()==true&&
parentNode?.IsUngroupedNode()==false)//不从“ungrouped”中删除对象类型
{
var group=(ObjectGroup)parentNode.Tag;
//从ObjectGroup中删除ObjectType,但不将其删除->变为“未分组”。
var cmd=(Commands.IGroupTypeCommand)mApplicationData.CommandFactory.Create(string.Concat(CommandPrefix,“TypeRemove”);
cmd.ObjectClass=t.Class;
cmd.ObjectTypeName=t.Name;
cmd.Data=group.Name;
cmd.Execute();
}
}
}
}
更新数据();
if(moveToThisNode!=null)
{
移动到此节点。确保可修改();
Show(“如果moveToThisNode不为null,则进行虚拟测试”);
}
}
我想出来了
问题是,在Remove()函数之后,会调用我的UpdateData()函数,该函数会重新绘制所有节点。所以在此之前调用EnsuleRevible()完全是胡说八道
因此,我所做的是,在Remove()中,我将要跳转到的节点的名称存储在一个成员变量中,在UpdateData()的末尾,我从TreeNodeCollection中获取具有该名称的节点,并(最后)为其调用EnsuRevible(),特别是提到-Or is moveToThisNode null???@TaW,我也发现了这篇文章,基本上就是我做的,除了第二个答案设置BindingIndex…我的节点没有这样的成员。另外,我也不太明白TopNode如何帮助我。并且,no moveToThisNode不为null,它显示文本框消息。TopNode会将某个节点移动到可见范围的顶部,而EnsureRevisible只会确保该节点可见(通过滚动和展开),但不一定在顶部。如果它实际上甚至不能为您做到这一点,那么您的代码中还有其他事情在进行尝试将moveToThisNode.Text添加到您显示的消息中@t我在消息中添加了moveToThisNode.Text,它显示了删除后我要位于的节点(=删除节点后的节点)。因此,如果我的节点是:A B C D,我删除B,消息框显示“C”,但可见部分又在开始处,我必须再次向下滚动(想象列表很长)@TaW这可能是,但感谢您花时间帮助我解决这个问题,我真的很感激。现在我只希望有人能给出答案:D Schönen Nachmittag noch!我在我的一个项目中也经历了类似的事情。我的代码在调用EnsureRevisible之后调用了TreeView.ExpandAll,这使得节点不再显示在视图中。经验教训:在将控件返回给用户之前,确保调用EnsureRevible是代码对TreeView执行的最后一项操作!
public override void Remove()
{
TreeNode moveToThisNode = treeControl1.SelectedNodes.Last().NextVisibleNode;
// first, group them by whether they are ObjectGroups or ObjectTypes
var grouping = from node in treeControl1.SelectedNodes
where !node.IsUngroupedNode()
let isGroup = node.IsGroupNode()
group node by isGroup into g
select new { IsGroupNode = g.Key, Items = g };
foreach (var grp in grouping)
{
foreach (var selectedNode in grp.Items)
{
// Only allow removal FIRSTLY of ObjectGroups and SECONDLY that are NOT the "ungrouped" group.
if (grp.IsGroupNode)
{
// Removes the Group
var cmd = (Commands.DataCommand<string>)mApplicationData.CommandFactory.Create(string.Concat(CommandPrefix, "Remove"));
cmd.Data = selectedNode.Text;
cmd.Execute();
}
else // ObjectType node --> just move to ungrouped
{
var t = (ObjectType)selectedNode.Tag;
var parentNode = selectedNode.Parent;
if (parentNode?.IsGroupNode() == true &&
parentNode?.IsUngroupedNode() == false) // No removal of ObjectTypes from within "ungrouped"
{
var group = (ObjectGroup)parentNode.Tag;
// Remove the ObjectType from the ObjectGroup but does not delete it -> becomes "ungrouped".
var cmd = (Commands.IGroupTypeCommand)mApplicationData.CommandFactory.Create(string.Concat(CommandPrefix, "TypeRemove"));
cmd.ObjectClass = t.Class;
cmd.ObjectTypeName = t.Name;
cmd.Data = group.Name;
cmd.Execute();
}
}
}
}
UpdateData();
if (moveToThisNode!=null)
{
moveToThisNode.EnsureVisible();
MessageBox.Show("Dummy test if moveToThisNode isn't null");
}
}