2012-06-20 14 views
6

Estoy tratando de diseñar un programa IDE (no editable) con un control richtextbox. Básicamente, necesito la vista de árbol que se coloca en el lado izquierdo del RTB para expandir/colapsar una cierta parte de mi código cada vez que el usuario hace clic en los botones +/-. Los rangos expandibles colapsables se definen como donde se vean los corchetes. Por ejemplo, en el RTB si tuviera algo como:C# Intrincado Treeview Design

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

Si tuviera que hacer clic en el soporte de la parte superior más rizado, que se derrumbaría todo dentro de la función principal. Básicamente, lo que está contenido dentro de esa llave es lo que está doblado. Entonces, en resumen, estoy tratando de diseñar algo que sea muy similar a la función de código expandir/contraer de Visual Studio, excepto que también lo hace con las funciones if/else.

Conozco el algoritmo de coincidencia de corchetes y implementé una pila para saber qué pares de corchetes coinciden (Números de línea almacenados en una lista de tuplas).

El problema que estoy teniendo principalmente es cómo diseñar el árbol de vista real. Necesito que treeview sea lineal, donde no se agregan nodos encima de otro. No conozco ningún enfoque que pueda agregar el botón expandir/colapsar sin agregar realmente nodos secundarios encima de otro nodo.

Además, con la excepción de los botones +/- y una línea vertical singular, necesito que los nodos de la vista de árbol sean no editables, no visibles y no se pueda hacer clic.

Finalmente, y esto es asumiendo que si cumplí con los requisitos anteriores, necesito que el evento de desplazamiento vertical del RTB también desplace correctamente la vista de árbol. Es decir, la sección de colapso/expansión de Treeview se actualizaría en función de la parte del código visible en el RTB.

Aquí es una sección del código que estoy utilizando para inicializar el árbol:

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++; 
     } 
    } 

Aquí está el código fuente Designer.sc, aunque creo que esto no va a ser realmente necesario, pero por si acaso:

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; 
    } 
} 

Realmente agradecería cualquier orientación para resolver este asunto. Gracias por adelantado.

Respuesta

7

Debería echar un vistazo a Scintilla y la versión de .NET aquí: http://scintillanet.codeplex.com/.

Incluye código fuente para resolver este tipo de problemas, aunque para ser honesto, simplemente usaría el control y lo haría de solo lectura para resolver sus requisitos de programación.

+0

Desafortunadamente, la descripción del problema anterior es exactamente lo que el cliente quería para el programa. Intenté abrir Scantilla, pero no se compila en mi máquina, por eso vine a buscar ayuda. – l46kok

+0

No necesita compilarlo solo use el archivo DLL agréguelo a Toolbox y simplemente arrastre sobre el formulario. – MMK

+0

En realidad, el programa que estoy desarrollando tiene fines comerciales y parece que no puedo usar el mencionado proyecto de código abierto debido a la licencia. – l46kok