📄 treelistview.cs
字号:
return br;
else
return null;
}
/// <summary>
/// Return the number of visible descendents that are below the given model.
/// </summary>
/// <param name="model">The model whose descendent count is to be returned</param>
/// <returns>The number of visible descendents. 0 if the model doesn't exist or is collapsed</returns>
public virtual int GetVisibleDescendentCount(object model)
{
Branch br = this.GetBranch(model);
if (br == null || !br.IsExpanded)
return 0;
else
return br.NumberVisibleDescendents;
}
/// <summary>
/// Rebuild the children of the given model, refreshing any cached information held about the given object
/// </summary>
/// <param name="model"></param>
/// <returns>The index of the model in flat list version of the tree</returns>
public virtual int RebuildChildren(Object model)
{
Branch br = this.GetBranch(model);
if (br == null)
return -1;
int count = br.NumberVisibleDescendents;
br.ClearCachedInfo();
// Remove the visible descendents from after the branch itself
int idx = this.GetObjectIndex(model);
if (count > 0)
this.objectList.RemoveRange(idx + 1, count);
if (br.IsExpanded)
this.InsertChildren(br, idx+1);
return idx;
}
//------------------------------------------------------------------------------------------
// Implementation
/// <summary>
/// Insert the children of the given branch into the given position
/// </summary>
/// <param name="br">The branch whose children should be inserted</param>
/// <param name="idx">The index where the children should be inserted</param>
protected virtual void InsertChildren(Branch br, int idx)
{
// Expand the branch
br.Expand();
br.Sort(this.GetBranchComparer());
// Insert the branch's visible descendents after the branch itself
this.objectList.InsertRange(idx, br.Flatten());
this.RebuildObjectMap(idx);
}
/// <summary>
/// Rebuild our flat internal list of objects.
/// </summary>
protected virtual void RebuildList()
{
this.objectList = ArrayList.Adapter(this.trunk.Flatten());
if (this.trunk.ChildBranches.Count > 0) {
this.trunk.ChildBranches[0].IsFirstBranch = true;
this.trunk.ChildBranches[0].IsOnlyBranch = (this.trunk.ChildBranches.Count == 1);
}
this.RebuildObjectMap(0);
}
/// <summary>
/// Rebuild our reverse index that maps an object to its location
/// in the objectList array.
/// </summary>
/// <param name="startIndex"></param>
protected virtual void RebuildObjectMap(int startIndex)
{
for (int i = startIndex; i < this.objectList.Count; i++)
this.mapObjectToIndex[this.objectList[i]] = i;
}
/// <summary>
/// Remember that the given branch is part of this tree.
/// </summary>
/// <param name="br"></param>
public virtual void RegisterBranch(Branch br)
{
this.mapObjectToBranch[br.Model] = br;
}
//------------------------------------------------------------------------------------------
#region IVirtualListDataSource Members
public virtual object GetNthObject(int n)
{
return this.objectList[n];
}
public virtual int GetObjectCount()
{
return this.trunk.NumberVisibleDescendents;
}
public virtual int GetObjectIndex(object model)
{
int idx;
if (model != null && this.mapObjectToIndex.TryGetValue(model, out idx))
return idx;
else
return -1;
}
public virtual void PrepareCache(int first, int last)
{
}
public virtual int SearchText(string value, int first, int last, OLVColumn column)
{
return AbstractVirtualListDataSource.DefaultSearchText(value, first, last, column, this);
}
public virtual void Sort(OLVColumn column, SortOrder order)
{
this.lastSortColumn = column;
this.lastSortOrder = order;
// Sorting is going to change the order of the branches so clear
// the "first branch" flag
if (this.trunk.ChildBranches.Count > 0)
this.trunk.ChildBranches[0].IsFirstBranch = false;
this.trunk.Sort(this.GetBranchComparer());
this.RebuildList();
}
protected virtual BranchComparer GetBranchComparer()
{
if (this.lastSortColumn == null)
return null;
else
return new BranchComparer(new ModelObjectComparer(this.lastSortColumn, this.lastSortOrder,
this.treeView.GetColumn(0), this.lastSortOrder));
}
public virtual void AddObjects(ICollection modelObjects)
{
ArrayList newRoots = new ArrayList();
foreach (Object x in this.treeView.Roots)
newRoots.Add(x);
foreach (Object x in modelObjects)
newRoots.Add(x);
this.SetObjects(newRoots);
}
public virtual void RemoveObjects(ICollection modelObjects)
{
ArrayList newRoots = new ArrayList();
foreach (Object x in this.treeView.Roots)
newRoots.Add(x);
foreach (Object x in modelObjects)
newRoots.Remove(x);
this.SetObjects(newRoots);
}
public virtual void SetObjects(IEnumerable collection)
{
// We interpret a SetObjects() call as setting the roots of the tree
this.treeView.Roots = collection;
}
#endregion
//------------------------------------------------------------------------------------------
// Private instance variables
private OLVColumn lastSortColumn;
private SortOrder lastSortOrder;
private Dictionary<Object, Branch> mapObjectToBranch = new Dictionary<object, Branch>();
private Dictionary<Object, int> mapObjectToIndex = new Dictionary<object,int>();
private ArrayList objectList = new ArrayList();
private TreeListView treeView;
private Branch trunk;
}
/// <summary>
/// A Branch represents a sub-tree within a tree
/// </summary>
protected class Branch
{
[Flags]
public enum BranchFlags {
FirstBranch = 1,
LastChild = 2,
OnlyBranch = 4
}
public Branch(Branch parent, Tree tree, Object model)
{
this.ParentBranch = parent;
this.Tree = tree;
this.Model = model;
if (parent != null)
this.Level = parent.Level + 1;
}
//------------------------------------------------------------------------------------------
// Properties
/// <summary>
/// Get the ancestor branches of this branch, with the 'oldest' ancestor first.
/// </summary>
public virtual IList<Branch> Ancestors
{
get {
List<Branch> ancestors = new List<Branch>();
if (this.ParentBranch != null)
this.ParentBranch.PushAncestors(ancestors);
return ancestors;
}
}
private void PushAncestors(IList<Branch> list)
{
// This is designed to ignore the trunk (which has no parent)
if (this.ParentBranch != null) {
this.ParentBranch.PushAncestors(list);
list.Add(this);
}
}
/// <summary>
/// Can this branch be expanded?
/// </summary>
public virtual bool CanExpand
{
get {
if (this.Tree.CanExpandGetter == null || this.Model == null)
return false;
else
return this.Tree.CanExpandGetter(this.Model);
}
}
/// <summary>
/// Get/set the model objects that are beneath this branch
/// </summary>
public virtual IEnumerable Children
{
get {
ArrayList children = new ArrayList();
foreach (Branch x in this.ChildBranches)
children.Add(x.Model);
return children;
}
set {
this.ChildBranches.Clear();
foreach (Object x in value)
this.AddChild(x);
if (this.ChildBranches.Count > 0)
this.ChildBranches[this.ChildBranches.Count - 1].IsLastChild = true;
}
}
private void AddChild(object model)
{
Branch br = this.Tree.GetBranch(model);
if (br == null)
br = this.MakeBranch(model);
this.ChildBranches.Add(br);
}
private Branch MakeBranch(object model)
{
Branch br = new Branch(this, this.Tree, model);
this.Tree.RegisterBranch(br);
return br;
}
/// <summary>
/// Return the number of descendents of this branch that are currently visible
/// </summary>
/// <returns></returns>
public virtual int NumberVisibleDescendents
{
get {
if (!this.IsExpanded)
return 0;
int count = this.ChildBranches.Count;
foreach (Branch br in this.ChildBranches)
count += br.NumberVisibleDescendents;
return count;
}
}
/// <summary>
/// Return true if this branch is the first branch of the entire tree
/// </summary>
public virtual bool IsFirstBranch
{
get {
return ((this.flags & Branch.BranchFlags.FirstBranch) != 0);
}
set {
if (value)
this.flags |= Branch.BranchFlags.FirstBranch;
else
this.flags &= ~Branch.BranchFlags.FirstBranch;
}
}
/// <summary>
/// Return true if this branch is the last child of its parent
/// </summary>
public virtual bool IsLastChild
{
get
{
return ((this.flags & Branch.BranchFlags.LastChild) != 0);
}
set
{
if (value)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -