我有一个包含很多节点的Treeview。如果我切换节点,树视图的滚动条将设置在底部。
为了保持切换节点可见,我使用node.EnsureVisible()
。但我不太喜欢这种方法,因为它让最终用户感到困惑。
所以我看得更远,现在我使用这里提供的代码:
Maintain scroll position of treeview
此代码的问题是,树视图的内容不会滚动。滚动条位于正确的位置,但内容不执行任何操作。在我点击滚动条(我不滚动)之前,内容变得可见。
所以,我想要实现的是当切换treenode时我想保持滚动位置。
切换节点的代码。在这种情况下,节点向下。功能如下所示:
// Check a node is selected
if (tvCategories.SelectedNode == null)
return;
// The first node may not be moved
if (IsNewRootCategorySelected())
return;
Point ScrollPos = GetTreeViewScrollPos(tvCategories);
// Declare and instantiate the parent node
TreeNodeCollection parent = null;
if (tvCategories.SelectedNode.Parent == null)
parent = tvCategories.Nodes;
else
parent = tvCategories.SelectedNode.Parent.Nodes;
TreeNode selectedNode = tvCategories.SelectedNode;
int index = selectedNode.Index;
// Check there's a next node at the same level
if (tvCategories.SelectedNode.NextNode == null)
{
// Check if the parent node has a next node
if (tvCategories.SelectedNode.Parent != null && tvCategories.SelectedNode.Parent.NextNode != null)
{
// get the destination parent
TreeNode destParent = selectedNode.Parent.NextNode;
// remove selected node from tree view
parent[index].Remove();
// If selected node is a category, add the node to the first index
if (selectedNode.Tag is Category)
{
destParent.Nodes.Insert(0, selectedNode);
}
// If selected node is a question, add node below last category
if (selectedNode.Tag is Question)
{
int newIndex = 0;
// Loop through collection to find last category
for (int i = destParent.Nodes.Count - 1; i >= 0; i--)
{
if (destParent.Nodes[i].Tag is Category)
{
newIndex = i + 1;
break;
}
}
destParent.Nodes.Insert(newIndex, selectedNode);
}
selectedNode.Expand();
}
}
else
{
// Switch nodes in same level
tvCategories.BeginUpdate();
_loading = true;
if (selectedNode.Tag is Category)
{
// Only switch category downwards when next node is a catgory
if (selectedNode.NextNode.Tag is Category)
{
// Perform switch
TreeNode switchNode = parent[index + 1];
parent[index + 1].Remove();
parent[index].Remove();
parent.Insert(index, switchNode);
parent.Insert(index + 1, selectedNode);
}
else if (selectedNode.NextNode.Tag is Question)
{
// Make the switch to another node below
if (selectedNode.Parent.NextNode != null)
{
// Parent is always a category
TreeNode categoryParent = selectedNode.Parent.NextNode;
// Remove selected node from current parent
parent.Remove(selectedNode);
// Insert selected node
categoryParent.Nodes.Insert(0, selectedNode);
}
}
}
if (selectedNode.Tag is Question)
{
if (selectedNode.NextNode.Tag is Question)
{
// Perform switch
TreeNode switchNode = parent[index + 1];
parent[index + 1].Remove();
parent[index].Remove();
parent.Insert(index, switchNode);
parent.Insert(index + 1, selectedNode);
}
}
}
tvCategories.EndUpdate();
// Set focus
tvCategories.Focus();
tvCategories.SelectedNode = selectedNode;
SetTreeViewScrollPos(tvCategories, ScrollPos);
答案 0 :(得分:0)
using System.Runtime.InteropServices;
[DllImport("user32.dll")]
static public extern int SendMessage(
IntPtr hWnd, // HWND handle to destination window
int Msg, // UINT message
int wParam, // WPARAM first message parameter
int lParam // LPARAM second message parameter
);
public const int SB_LINEUP = 0;
public const int SB_LINELEFT = 0;
public const int SB_LINEDOWN = 1;
public const int SB_LINERIGHT = 1;
public const int SB_PAGEUP = 2;
public const int SB_PAGELEFT = 2;
public const int SB_PAGEDOWN = 3;
public const int SB_PAGERIGHT = 3;
public const int SB_THUMBPOSITION = 4;
public const int SB_THUMBTRACK = 5;
public const int SB_TOP = 6;
public const int SB_LEFT = 6;
public const int SB_BOTTOM = 7;
public const int SB_RIGHT = 7;
public const int SB_ENDSCROLL = 8;
public const int WM_HSCROLL = 276;
public const int WM_VSCROLL = 277;
public void eZScroll(TreeView treeView, ArrowDirection direction, int numScrolls)
{
int Msg = 0;
int wParam = 0;
int lParam = 0;
switch (direction)
{
case ArrowDirection.Up:
Msg = WM_VSCROLL;
wParam = SB_LINEUP;
break;
case ArrowDirection.Down:
Msg = WM_VSCROLL;
wParam = SB_LINEDOWN;
break;
case ArrowDirection.Left:
Msg = WM_HSCROLL;
wParam = SB_LINELEFT;
break;
case ArrowDirection.Right:
Msg = WM_HSCROLL;
wParam = SB_LINERIGHT;
break;
}
for (int i = 0; i < numScrolls; i++)
{
SendMessage(treeView.Handle, Msg, wParam, lParam);
}
}
在以下地方粘贴:
public Form1()
{
InitializeComponent();
}
这样打电话:
eZScroll(treeView1, ArrowDirection.Up, 1);
我不确定这段代码是否可以直接使用,但我相信它能帮助您解决问题。