使用Dev TreeList时,每当新增、修改、删除节点时,树就会闪烁,而且节点的展开状态混乱,滚动条也乱跳,解决这个问题思路很简单:
1.操作树之前保存树的当前状态,如节点的展开状态(只保存展开即可)、当前焦点、当前距顶位置等。
2.操作完树(调用RefreshDataSource)后,重新设置树的状态。
重点:
能使树不闪烁的关键代码是TreeList.BeginUpdate();和TreeList.EndUpdate();这两个方法要成对使用,否则还是会造成闪烁,切记一定要成对使用。
为了让整个操作过程中树不闪烁,切记,一次操作只能对树的状态保存一次,在保存状态方法里使用TreeList.BeginUpdate(),加载一次,在加载状态方法里使用TreeList.EndUpdate(),保存和记载之间只能调用一次树的刷新RefreshDataSource.
贴上树状态的保存加载类:
public class TreeListViewState
{
private List<string> expandNodeList;
private List<string> visibleNodeList;
private string focusedId;
private TreeListNode preNode;
private int topIndex;
private Stack<bool> stateStack;
public TreeListViewState() : this(null) { }
public TreeListViewState(TreeList treeList)
{
this.treeList = treeList;
expandNodeList = new List<string>();
visibleNodeList = new List<string>();
stateStack = new Stack<bool>();
}
public bool IsRefreshing { get; set; } = false;
public void Clear()
{
expandNodeList.Clear();
visibleNodeList.Clear();
stateStack.Clear();
focusedId = string.Empty;
preNode = null;
topIndex = 0;
}
private void GetExpandedAndVisibled()
{
expandNodeList.Clear();
visibleNodeList.Clear();
// 备注:TreeList.GetNodeList()返回集合中不包含visible为false的节点
foreach (var node in TreeList.GetNodeList())
{
if(node.ParentNode != null && !node.ParentNode.Visible)
{
visibleNodeList.Add(node.ParentNode.GetValue("Id")?.ToString());
}
if (node.HasChildren && node.Expanded)
{
expandNodeList.Add(node.GetValue("Id")?.ToString());
}
}
expandNodeList.RemoveAll(o => string.IsNullOrEmpty(o));
visibleNodeList.RemoveAll(o => string.IsNullOrEmpty(o));
visibleNodeList = visibleNodeList.Distinct().ToList();
}
private ArrayList GetSelected()
{
ArrayList al = new ArrayList();
foreach (TreeListNode node in TreeList.Selection)
al.Add(node.GetValue(TreeList.KeyFieldName));
return al;
}
public void LoadState()
{
try
{
if (stateStack.Count == 0) return;
if (!stateStack.Pop())
return;
TreeList.RefreshDataSource();
IsRefreshing = false;
foreach (TreeListNode item in TreeList.GetNodeList())
{
if (expandNodeList.Contains(item.GetValue("Id")?.ToString()))
{
item.Expanded = true;
}
else
{
item.Expanded = false;
}
if (visibleNodeList.Contains(item.GetValue("Id")?.ToString()))
{
item.Visible = false;
}
}
var focusedNode = TreeList.FindNodeByFieldValue("Id", focusedId);
if (focusedNode == null)
{
TreeList.FocusedNode = preNode;
}
else
{
TreeList.FocusedNode = TreeList.FindNodeByFieldValue("Id", focusedId);
}
TreeList.TopVisibleNodeIndex = TreeList.GetVisibleIndexByNode(TreeList.FocusedNode) - topIndex;
TreeList.EndUpdate();
Console.WriteLine("LoadState");
}
catch(Exception ex)
{
ErrorLogOutputService.Instance().Output(ex);
}
}
public void SaveState(bool isLock = false)
{
if (stateStack.Count == 0)
{
stateStack.Push(true);
}
else
{
stateStack.Push(false);
return;
}
Console.WriteLine("SaveState");
TreeList.BeginUpdate();
if (TreeList.FocusedNode != null)
{
GetExpandedAndVisibled();
focusedId = TreeList.FocusedNode.GetValue("Id")?.ToString();
preNode = TreeList.FocusedNode.PrevNode == null ? TreeList.FocusedNode.ParentNode : TreeList.FocusedNode.PrevNode;
topIndex = TreeList.GetVisibleIndexByNode(TreeList.FocusedNode) - TreeList.TopVisibleNodeIndex;
IsRefreshing = true;
}
else
{
Clear();
}
}
private TreeList treeList;
public TreeList TreeList
{
get
{
return treeList;
}
set
{
treeList = value;
Clear();
}
}
}