C # Sophisticated Treeview Design

I am trying to create an IDE-like (non-editable) program with a richtextbox control. Basically, I need a tree, which is located to the left of RTB, to expand / collapse part of my code whenever a user presses the +/- buttons. Expandable expandable ranges are defined as wherever braces are visible. For example, in RTB, if I had something like:

int main() { if (...) { if (...) { } } else { } } 

If I clicked on the topmost brace, it would destroy everything inside the main function. Basically, what is contained within this curly brace is what develops. So, in general, I'm trying to create something that is very similar to the Visual Studio expand / collapse function, except that it also works with if / else functions.

I know the parenthesis matching algorithm, and I implemented a stack to find out which pairs of parentheses match (line numbers are stored in the tuple list).

The problem I am facing is how to get started developing the actual tree. I need the tree structure to be linear, where no node is added on top of the other. I don't know of any approach that can add the expand / collapse button without actually adding child nodes on top of another node.

In addition, with the exception of the +/- buttons and the only vertical line, I need the tree nodes to be inaccessible for editing, invisible and not clickable.

Finally, and this assumes that if I have fulfilled the above requirements, I need the RTB vertical scroll event to properly scroll through the tree structure. That is, the Treeview collapse / expand section will be updated based on the part of the code visible in RTB.

Here is the section of code that I use to initialize the tree:

 public partial class LogicSimulationViewerForm : Form { private List<Tuple<string,Boolean>> visibleLines = new List<Tuple<string,Boolean>>(); private List<Tuple<int, int>> collapseRange = new List<Tuple<int, int>>(); private void TreeInit() { TreeNode tn; Stack<int> openBracketLine = new Stack<int>(); int i = 0; TreeLogicCode.Nodes.Clear(); foreach (string s in rtbLogicCode.Lines) { visibleLines.Add(Tuple.Create(s, true)); if (s == "{") { openBracketLine.Push(i); } else if (s == "}") { collapseRange.Add(Tuple.Create(openBracketLine.Pop(),i)); } i++; } } 

Here is the source code for Designer.sc, although I believe that this is not really necessary, but just in case:

 namespace DDCUI { partial class LogicSimulationViewerForm { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.TreeLogicCode = new System.Windows.Forms.TreeView(); this.labelLogicCode = new System.Windows.Forms.Label(); this.rtbLogicCode = new System.Windows.Forms.RichTextBox(); this.SuspendLayout(); // // TreeLogicCode // this.TreeLogicCode.Dock = System.Windows.Forms.DockStyle.Left; this.TreeLogicCode.Location = new System.Drawing.Point(50, 0); this.TreeLogicCode.Name = "TreeLogicCode"; this.TreeLogicCode.Scrollable = false; this.TreeLogicCode.Size = new System.Drawing.Size(40, 600); this.TreeLogicCode.TabIndex = 4; // // labelLogicCode // this.labelLogicCode.BackColor = System.Drawing.Color.LightGray; this.labelLogicCode.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.labelLogicCode.Dock = System.Windows.Forms.DockStyle.Left; this.labelLogicCode.ForeColor = System.Drawing.SystemColors.ControlText; this.labelLogicCode.Location = new System.Drawing.Point(0, 0); this.labelLogicCode.Margin = new System.Windows.Forms.Padding(3); this.labelLogicCode.Name = "labelLogicCode"; this.labelLogicCode.Padding = new System.Windows.Forms.Padding(3); this.labelLogicCode.Size = new System.Drawing.Size(50, 600); this.labelLogicCode.TabIndex = 3; this.labelLogicCode.TextAlign = System.Drawing.ContentAlignment.TopRight; // // rtbLogicCode // this.rtbLogicCode.Dock = System.Windows.Forms.DockStyle.Fill; this.rtbLogicCode.Location = new System.Drawing.Point(90, 0); this.rtbLogicCode.Name = "rtbLogicCode"; this.rtbLogicCode.Size = new System.Drawing.Size(510, 600); this.rtbLogicCode.TabIndex = 5; this.rtbLogicCode.Text = ""; this.rtbLogicCode.VScroll += new System.EventHandler(this.rtbLogicCode_VScroll); // // LogicSimulationViewerForm // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(600, 600); this.Controls.Add(this.rtbLogicCode); this.Controls.Add(this.TreeLogicCode); this.Controls.Add(this.labelLogicCode); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; this.Name = "LogicSimulationViewerForm"; this.Text = "LogicSimulationViewerForm"; this.ResumeLayout(false); } #endregion private System.Windows.Forms.TreeView TreeLogicCode; private System.Windows.Forms.Label labelLogicCode; private System.Windows.Forms.RichTextBox rtbLogicCode; } } 

I would really appreciate any advice on resolving this issue. Thanks in advance.

+6
source share
1 answer

You should take a look at Scintilla and the .NET version here: http://scintillanet.codeplex.com/ .

It contains source code to solve these problems, although to be honest, I just use the control and make it read-only to solve your programming requirements.

+7
source

Source: https://habr.com/ru/post/918526/


All Articles