⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 treelistview.cs

📁 Linux 恢复盘制作工具 process调用busybox dd实现写*.img镜像
💻 CS
📖 第 1 页 / 共 4 页
字号:
                        this.flags |= Branch.BranchFlags.LastChild;
                    else
                        this.flags &= ~Branch.BranchFlags.LastChild;
                }
            }

            /// <summary>
            /// Return true if this branch is the only top level branch
            /// </summary>
            public virtual bool IsOnlyBranch
            {
                get
                {
                    return ((this.flags & Branch.BranchFlags.OnlyBranch) != 0);
                }
                set
                {
                    if (value)
                        this.flags |= Branch.BranchFlags.OnlyBranch;
                    else
                        this.flags &= ~Branch.BranchFlags.OnlyBranch;
                }
            }
	
            //------------------------------------------------------------------------------------------
            // Commands

            /// <summary>
            /// Clear any cached information that this branch is holding
            /// </summary>
            public virtual void ClearCachedInfo()
            {
                this.Children = new ArrayList();
                this.alreadyHasChildren = false;
            }

            /// <summary>
            /// Collapse this branch
            /// </summary>
            public virtual void Collapse()
            {
                this.IsExpanded = false;
            }

            /// <summary>
            /// Expand this branch
            /// </summary>
            public virtual void Expand()
            {
                if (!this.CanExpand)
                    return;

                // THINK: Should we cache the children or fetch them each time? If we cache, we need a "DiscardCache" ability

                this.IsExpanded = true;
                if (this.alreadyHasChildren)
                    return;

                if (this.Tree.ChildrenGetter != null) {
                    Cursor previous = Cursor.Current;
                    try {
                        if (this.Tree.TreeView.UseWaitCursorWhenExpanding)
                            Cursor.Current = Cursors.WaitCursor;
                        this.Children = this.Tree.ChildrenGetter(this.Model);
                    }
                    finally {
                        if (this.Tree.TreeView.UseWaitCursorWhenExpanding)
                            Cursor.Current = previous;
                    }
                }

                this.alreadyHasChildren = true;
            }

            /// <summary>
            /// Expand this branch recursively
            /// </summary>
            public virtual void ExpandAll()
            {
                this.Expand();
                foreach (Branch br in this.ChildBranches)
                    br.ExpandAll();
            }

            /// <summary>
            /// Collapse the visible descendents of this branch into list of model objects
            /// </summary>
            /// <returns></returns>
            public virtual IList Flatten()
            {
                ArrayList flatList = new ArrayList();
                if (this.IsExpanded)
                    this.FlattenOnto(flatList);
                return flatList;
            }  

            /// <summary>
            /// Flatten this branch's visible descendents onto the given list.
            /// </summary>
            /// <param name="flatList"></param>
            /// <remarks>The branch itself is <b>not</b> included in the list.</remarks>
            public virtual void FlattenOnto(IList flatList)
            {
                foreach (Branch br in this.ChildBranches) {
                    flatList.Add(br.Model);
                    if (br.IsExpanded)
                        br.FlattenOnto(flatList);
                }
            }

            /// <summary>
            /// Sort the sub-branches and their descendents so they are ordered according
            /// to the given comparer.
            /// </summary>
            /// <param name="comparer">The comparer that orders the branches</param>
            public virtual void Sort(BranchComparer comparer)
            {
                if (comparer == null || this.ChildBranches.Count == 0)
                    return;
                
                // We're about to sort the children, so clear the last child flag
                this.ChildBranches[this.ChildBranches.Count - 1].IsLastChild = false;

                this.ChildBranches.Sort(comparer);
                this.ChildBranches[this.ChildBranches.Count - 1].IsLastChild = true;

                foreach (Branch br in this.ChildBranches)
                    br.Sort(comparer);
            }

            //------------------------------------------------------------------------------------------
            // Public instance variables

            public Object Model;
            public Tree Tree;
            public Branch ParentBranch;
            public List<Branch> ChildBranches = new List<Branch>();
            //public bool CanExpand = false;
            public bool IsExpanded = false;
            public int Level = 0;

            //------------------------------------------------------------------------------------------
            // Private instance variables

            private bool alreadyHasChildren = false;
            private BranchFlags flags;          
        }

        /// <summary>
        /// This class sorts branches according to how their respective model objects are sorted
        /// </summary>
        protected class BranchComparer : IComparer<Branch>
        {
            public BranchComparer(IComparer actualComparer)
            {
                this.actualComparer = actualComparer;
            }

            public int Compare(Branch x, Branch y)
            {
                return this.actualComparer.Compare(x.Model, y.Model);
            }

            private IComparer actualComparer;
        }

        /// <summary>
        /// This class handles drawing the tree structure of the primary column.
        /// </summary>
        public class TreeRenderer : BaseRenderer
        {
            public TreeRenderer()
            {
                this.LinePen =  new Pen(Color.Blue, 1.0f);
                this.LinePen.DashStyle = DashStyle.Dot;
            }

            /// <summary>
            /// Return the branch that the renderer is currently drawing.
            /// </summary>
            private Branch Branch
            {
                get {
                    return this.TreeListView.TreeModel.GetBranch(this.RowObject);
                }
            }

            /// <summary>
            /// Return the pen that will be used to draw the lines between branches
            /// </summary>
            public Pen LinePen
            {
                get { return linePen; }
                set { linePen = value; }
            }
            private Pen linePen;
	
            /// <summary>
            /// Return the TreeListView for which the renderer is being used.
            /// </summary>
            public TreeListView TreeListView
            {
                get {
                    return (TreeListView)this.ListView;
                }
            }

            /// <summary>
            /// Should the renderer draw lines connecting siblings?
            /// </summary>
            public bool IsShowLines = true;

            /// <summary>
            /// How many pixels will be reserved for each level of indentation?
            /// </summary>
            public static int PIXELS_PER_LEVEL = 16 + 1;

            /// <summary>
            /// The real work of drawing the tree is done in this method
            /// </summary>
            /// <param name="g"></param>
            /// <param name="r"></param>
            public override void Render(System.Drawing.Graphics g, System.Drawing.Rectangle r)
            {
                this.DrawBackground(g, r);

                Branch br = this.Branch;

                if (this.IsShowLines)
                    this.DrawLines(g, r, this.LinePen, br);

                if (br.CanExpand) {
                    Rectangle r2 = r;
                    r2.Offset((br.Level - 1) * PIXELS_PER_LEVEL, 0);
                    r2.Width = PIXELS_PER_LEVEL;

                    if (!this.IsPrinting && Application.RenderWithVisualStyles) {
                        VisualStyleElement element = VisualStyleElement.TreeView.Glyph.Closed;
                        if (br.IsExpanded)
                            element = VisualStyleElement.TreeView.Glyph.Opened;
                        VisualStyleRenderer renderer = new VisualStyleRenderer(element);
                        renderer.DrawBackground(g, r2);
                    } else {
                        int h = 8;
                        int w = 8;
                        int x = r2.X + 4;
                        int y = r2.Y + (r2.Height / 2) - 4;

                        g.DrawRectangle(new Pen(SystemBrushes.ControlDark), x, y, w, h);
                        g.FillRectangle(Brushes.White, x + 1, y + 1, w - 1, h - 1);
                        g.DrawLine(Pens.Black, x + 2, y + 4, x + w - 2, y + 4);

                        if (!br.IsExpanded)
                            g.DrawLine(Pens.Black, x + 4, y + 2, x + 4, y + h - 2);
                    } 
                }

                int indent = br.Level * PIXELS_PER_LEVEL;
                r.Offset(indent, 0);
                r.Width -= indent;

                this.DrawImageAndText(g, r);
            }

            private void DrawLines(Graphics g, Rectangle r, Pen p, Branch br)
            {
                Rectangle r2 = r;
                r2.Width = PIXELS_PER_LEVEL;
                
                // Vertical lines have to start on even points, otherwise the dotted line looks wrong.
                // This isn't need if pen isn't dotted.
                int top = r2.Top;
                if (p.DashStyle == DashStyle.Dot && (top & 1) == 1)
                    top += 1;

                // Draw lines for ancestors
                int midX;
                IList<Branch> ancestors = br.Ancestors;
                foreach (Branch ancestor in ancestors) {
                    if (!ancestor.IsLastChild) {
                        midX = r2.Left + r2.Width / 2;
                        g.DrawLine(p, midX, top, midX, r2.Bottom);
                    }
                    r2.Offset(PIXELS_PER_LEVEL, 0);
                }

                // Draw lines for this branch
                midX = r2.Left + r2.Width / 2;
                int midY = r2.Top + r2.Height / 2;
                // Horizontal line first
                g.DrawLine(p, midX, midY, r2.Right, midY);
                // Vertical line second
                if (br.IsFirstBranch) {
                    if (!br.IsOnlyBranch)
                        g.DrawLine(p, midX, midY, midX, r2.Bottom);
                }  else {
                    if (br.IsLastChild)
                        g.DrawLine(p, midX, top, midX, midY);
                    else
                        g.DrawLine(p, midX, top, midX, r2.Bottom);
                }
            }

            protected override void HandleHitTest(Graphics g, OlvListViewHitTestInfo hti, int x, int y)
            {
                Branch br = this.Branch;

                Rectangle r = this.Bounds;
                if (br.CanExpand) {
                    r.Offset((br.Level - 1) * PIXELS_PER_LEVEL, 0);
                    r.Width = PIXELS_PER_LEVEL;
                    if (r.Contains(x, y)) {
                        hti.HitTestLocation = HitTestLocation.ExpandButton;
                        return;
                    }
                }

                r = this.Bounds;
                int indent = br.Level * PIXELS_PER_LEVEL;
                r.X += indent;
                r.Width -= indent;
                this.StandardHitTest(g, hti, r, x, y);
            }
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -