[C#/WPF/AVALON] 코드 편집기(Code Editor) 사용하기
■ 코드 편집기(Code Editor)를 사용하는 방법을 보여준다. ▶ BraceFoldingStrategy.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
using System.Collections.Generic; using ICSharpCode.AvalonEdit.Document; using ICSharpCode.AvalonEdit.Folding; namespace TestProject { /// <summary> /// 중괄호 폴딩 전략 /// </summary> public class BraceFoldingStrategy { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 개방 중괄호 - OpeningBrace /// <summary> /// 개방 중괄호 /// </summary> public char OpeningBrace { get; set; } #endregion #region 폐쇄 중괄호 - ClosingBrace /// <summary> /// 폐쇄 중괄호 /// </summary> public char ClosingBrace { get; set; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - BraceFoldingStrategy() /// <summary> /// 생성자 /// </summary> public BraceFoldingStrategy() { OpeningBrace = '{'; ClosingBrace = '}'; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 새 폴딩 생성하기 - CreateNewFoldings(source) /// <summary> /// 새 폴딩 생성하기 /// </summary> /// <param name="source">텍스트 소스</param> /// <returns>새 폴딩 열거 가능형</returns> public IEnumerable<NewFolding> CreateNewFoldings(ITextSource source) { List<NewFolding> newFoldingList = new List<NewFolding>(); Stack<int> offsetStack = new Stack<int>(); int lastNewLineOffset = 0; char openingBrace = OpeningBrace; char closingBrace = ClosingBrace; for(int i = 0; i < source.TextLength; i++) { char character = source.GetCharAt(i); if(character == openingBrace) { offsetStack.Push(i); } else if(character == closingBrace && offsetStack.Count > 0) { int startOffset = offsetStack.Pop(); if(startOffset < lastNewLineOffset) { newFoldingList.Add(new NewFolding(startOffset, i + 1)); } } else if(character == '\n' || character == '\r') { lastNewLineOffset = i + 1; } } newFoldingList.Sort((a,b) => a.StartOffset.CompareTo(b.StartOffset)); return newFoldingList; } #endregion #region 새 폴딩 생성하기 - CreateNewFoldings(document, firstErrorOffset) /// <summary> /// 새 폴딩 생성하기 /// </summary> /// <param name="document">텍스트 문서</param> /// <param name="firstErrorOffset">첫번째 에러 오프셋</param> /// <returns>새 폴딩 열거 가능형</returns> public IEnumerable<NewFolding> CreateNewFoldings(TextDocument document, out int firstErrorOffset) { firstErrorOffset = -1; return CreateNewFoldings(document); } #endregion #region 폴딩 업데이트하기 - UpdateFoldings(manager, document) /// <summary> /// 폴딩 업데이트하기 /// </summary> /// <param name="manager">폴딩 관리자</param> /// <param name="document">텍스트 문서</param> public void UpdateFoldings(FoldingManager manager, TextDocument document) { int firstErrorOffset; IEnumerable<NewFolding> newFoldingEnumerable = CreateNewFoldings(document, out firstErrorOffset); manager.UpdateFoldings(newFoldingEnumerable, firstErrorOffset); } #endregion } } |
▶ MainWindow.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<Window x:Class="TestProject.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:avalonEdit="http://icsharpcode.net/sharpdevelop/avalonedit" Width="800" Height="600" Title="코드 편집기(Code Editor) 사용하기" FontFamily="나눔고딕코딩" FontSize="16"> <Grid Margin="10"> <Border BorderBrush="Black" BorderThickness="1" SnapsToDevicePixels="True"> <avalonEdit:TextEditor Name="textEditor" /> </Border> </Grid> </Window> |
▶ MainWindow.xaml.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
using System.Windows; using ICSharpCode.AvalonEdit.Folding; using ICSharpCode.AvalonEdit.Highlighting; namespace TestProject { /// <summary> /// 메인 윈도우 /// </summary> public partial class MainWindow : Window { //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - MainWindow() /// <summary> /// 생성자 /// </summary> public MainWindow() { InitializeComponent(); this.textEditor.IsReadOnly = true; // 디폴트 : false this.textEditor.Options.AllowScrollBelowDocument = true; // 디폴트 : false this.textEditor.Options.AllowToggleOverstrikeMode = true; // 디폴트 : false this.textEditor.Options.ColumnRulerPosition = 130; // 디폴트 : 80 this.textEditor.Options.ConvertTabsToSpaces = true; // 디폴트 : false this.textEditor.Options.CutCopyWholeLine = true; // 디폴트 : true this.textEditor.Options.EnableEmailHyperlinks = true; // 디폴트 : true this.textEditor.Options.EnableHyperlinks = true; // 디폴트 : true this.textEditor.Options.EnableImeSupport = true; // 디폴트 : true this.textEditor.Options.EnableRectangularSelection = true; // 디폴트 : true this.textEditor.Options.EnableTextDragDrop = true; // 디폴트 : true this.textEditor.Options.EnableVirtualSpace = true; // 디폴트 : false this.textEditor.Options.HideCursorWhileTyping = true; // 디폴트 : true this.textEditor.Options.HighlightCurrentLine = true; // 디폴트 : false this.textEditor.Options.IndentationSize = 4; // 디폴트 : 4 this.textEditor.Options.InheritWordWrapIndentation = true; // 디폴트 : true this.textEditor.Options.RequireControlModifierForHyperlinkClick = true; // 디폴트 : true this.textEditor.Options.ShowBoxForControlCharacters = true; // 디폴트 : true this.textEditor.Options.ShowColumnRuler = true; // 디폴트 : false this.textEditor.Options.ShowEndOfLine = false; // 디폴트 : false this.textEditor.Options.ShowSpaces = false; // 디폴트 : false this.textEditor.Options.ShowTabs = false; // 디폴트 : false this.textEditor.Options.WordWrapIndentation = 0; // 디폴트 : 0 this.textEditor.ShowLineNumbers = true; // 디폴트 : false this.textEditor.WordWrap = false; // 디폴트 : false Loaded += Window_Loaded; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Private #region 윈도우 로드시 처리하기 - Window_Loaded(sender, e) /// <summary> /// 윈도우 로드시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void Window_Loaded(object sender, RoutedEventArgs e) { this.textEditor.Load(@"..\..\MainWindow.xaml.cs"); #region name /* XmlDoc C# JavaScript HTML ASP/XHTML Boo Coco CSS C++ Java Patch PowerShell PHP Python TeX TSQL VB XML MarkDown MarkDownWithFontSize Json */ #endregion IHighlightingDefinition definition = HighlightingManager.Instance.GetDefinition("C#"); this.textEditor.SyntaxHighlighting = definition; // 디폴트 : null FoldingManager foldingManager = FoldingManager.Install(this.textEditor.TextArea); //XmlFoldingStrategy foldingStrategy = new XmlFoldingStrategy(); BraceFoldingStrategy foldingStrategy = new BraceFoldingStrategy(); foldingStrategy.UpdateFoldings(foldingManager, this.textEditor.Document); } #endregion } } |
TestProject.zip