2012-06-20 8 views
6

Próbuję zaprojektować program podobny do IDE (Non-Editable) z formantem richtextbox. Zasadniczo potrzebuję widoku drzewa, które jest umieszczone po lewej stronie RTB, aby rozwinąć/zwinąć pewną część mojego kodu za każdym razem, gdy użytkownik kliknie przycisk +/-. Rozszerzalne zwijane zakresy są zdefiniowane jako miejsca, w których widoczne są nawiasy klamrowe. Na przykład w RTB gdybym miał coś takiego:C# Intricate Treeview Design

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

Gdybym kliknij na górnym najbardziej nawias klamrowy, byłoby zwinąć wszystko wewnątrz funkcji main. Zasadniczo, co jest zawarte w tym nawiasie klamrowym, jest to, co jest złożone. Podsumowując, próbuję zaprojektować coś, co jest bardzo podobne do funkcji rozszerzania/zwijania kodu Visual Studio, oprócz tego, że robi to także z funkcjami if/else.

Jestem świadomy algorytmu dopasowywania nawiasów i zaimplementowałem stos, aby wiedzieć, które pary nawiasów pasują do siebie (numery linii przechowywane na liście krotek).

Problem, który mam poważnie, dotyczy sposobu projektowania rzeczywistego widoku drzewa. Potrzebuję widoku drzewa w liniowy sposób, w którym żadne węzły nie są dodawane na drugim. Nie jestem świadomy żadnego podejścia, które może dodać przycisk rozwijania/zwijania bez faktycznego dodawania węzłów potomnych do innego węzła.

Ponadto, z wyjątkiem przycisków +/- i pojedynczej linii pionowej, potrzebuję węzłów widoku drzewa, które nie będą edytowalne, niewidoczne ani nieklikalne.

Wreszcie i zakładam, że jeśli spełniłem powyższe wymagania, potrzebuję pionowego zdarzenia przewijania RTB, aby poprawnie przewinąć również widok drzewa. Oznacza to, że sekcja zwijania/powiększania drzewa będzie aktualizowana na podstawie fragmentu kodu widocznego w RTB.

Oto fragment kodu używam do zainicjowania drzewa:

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

Oto kod źródłowy Designer.sc, chociaż uważam, że nie będzie to naprawdę konieczne, ale na wszelki wypadek:

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

Byłbym wdzięczny za wszelkie wskazówki dotyczące rozwiązania tej kwestii. Z góry dziękuję.

Odpowiedz

7

Powinieneś rzucić okiem na Scintillę i wersję .NET tutaj: http://scintillanet.codeplex.com/.

Zawiera kod źródłowy do rozwiązywania tego typu problemów, ale szczerze mówiąc, po prostu użyłbym kontroli i uczynię ją tylko do odczytu, aby rozwiązać twoje wymagania programistyczne.

+0

Niestety, powyższy opis problemu jest dokładnie tym, czego żądał klient dla programu. Próbowałem otworzyć Scantillę, ale nie skompilowałem się na moim komputerze, dlatego przyjechałem tu po pomoc. – l46kok

+0

Nie trzeba go kompilować, wystarczy skorzystać z biblioteki DLL, dodać ją do Toolbox i przeciągnąć po formularzu. – MMK

+0

W rzeczywistości program, który rozwijam, jest przeznaczony do celów komercyjnych i wydaje się, że nie mogę używać wspomnianego projektu open source z powodu licencji. – l46kok