SyntaxEditor - basic questions

10 Answers 47 Views
SyntaxEditor
Marian
Top achievements
Rank 1
Iron
Iron
Iron
Marian asked on 15 Jun 2022, 07:11 PM | edited on 15 Jun 2022, 07:14 PM

Hello, sorry, maybe I am too new to Telerik, but I was wondering how to do basic tasks with SyntaxEditor. I wanted to replace classic TextBox with SyntaxEditor and I thought it would be straightforward, but I got stuck on very basic tasks. Can you please help me, or navigate me?

1. How to get text from SyntaxEditor? I know how to set text by setting new document, but how to get text? I read whole SyntaxEditor part of documentation, but haven't found this, how is it possible? I was trying to find this out for about hour, but without success. I am wondering if am too new to Telerik or how it's possible I couldn't find this, I think this basic thing must be like "look and see".

2. Classic WinForms TextBox has Modified property indicating the text was changed. Is it also somewhere here? Also, TextBox has Lines property, is it somewhere here?

3. I tried the Cut/Copy/Paste commands, they are working, but I was wondering why CanExecute methods return always true. For example, I expect if there is no selection, CanExecute for Cut and Copy has to return false. Also, if there is no text in clipboard, Paste command has to return false, etc.

Marian
Top achievements
Rank 1
Iron
Iron
Iron
commented on 15 Jun 2022, 10:12 PM

Now I have figured out the first question, it's accessible through radSyntaxEditor1.Document.CurrentSnapshot.GetText(), or lines are accessible through radSyntaxEditor1.Document.CurrentSnapshot.Lines[]. I tried to google it without winforms keyword and has found it in similar question to WPF version of SyntaxEditor.

And, if my questions would seem little bit upset, I'm sorry, I think when I will manage upgrade to SyntaxEditor, I think it will be great enhancement of our editor, it's great control. I started with playing with coloring, folding, completions etc, I was excited about the features I can use, and after two days of playing with control got to implementation and I was surprised I couldn't find it.

Dinko | Tech Support Engineer
Telerik team
commented on 16 Jun 2022, 12:40 PM

Thank you for your kind words. We appreciate it. Regarding your questions, I will do my best to help you to migrate your TextBox controls to RadSyntaxEditor. I see that you have found the GetText() method to get the content of the control. You can check the lines from the radSyntaxEditor1.Document.CurrentSnapshot.Lines as you have already found. Now the control does not expose such Modified property. However, you could subscribe to the DocumentContentChanged event and raise a flag when it is called. This event will be called when the application starts and after the user has changed the content of the control.

As for the commands, the CanExecute by default returns true. No logic checks whether the text is selected or the clipboard contains a text. You can cancel the commands in the mySyntaxEditor.SyntaxEditorElement.CommandExecuting event handler. 

If you have any other questions feel free to ask.

Marian
Top achievements
Rank 1
Iron
Iron
Iron
commented on 16 Jun 2022, 01:10 PM

Ok, so I have to do Modified flag myself, it's not problem. Also it's no problem to do logic for checking if text is selected, clipboard contains text etc, but if CanExecute simply returns true, what's the meaning of this method? I thought I will just use CanExecute to enable / disable toolbar buttons. Of course, I can simply do it myself.

I have used more properties / methods of TextBox in this editor, like SelectionStart, End, GetLineFromCharIndex, ScrollToCaret, for example for expanding selection to whole lines and commenting/uncommenting lines, but I have found some similar methods of selections and caret positions in SyntaxEditor, so I think I will solve it after some time of playing. I was trying some tests and this tasks seems to be easier in SyntaxEditor, so maybe my methods for this will be simplified.

If I will have more questions, I will ask later.

Dinko | Tech Support Engineer
Telerik team
commented on 17 Jun 2022, 10:38 AM

The CanExecute method comes from the SyntaxEditorCommandBase abstract class which the commands of the RadSyntaxEditor derive from. This is an inherited property and that is why is visible in the mentioned commands. It was created for internal use. While developing the control it was decided to create a global event that will catch all commands before executing. This way you won't need to subscribe to each command. As mentioned above, you can cancel a command in the mySyntaxEditor.SyntaxEditorElement.CommandExecuting event handler. 

10 Answers, 1 is accepted

Sort by
0
Marian
Top achievements
Rank 1
Iron
Iron
Iron
answered on 23 Jun 2022, 09:15 PM | edited on 23 Jun 2022, 09:43 PM

Hello, I have more questions. I'm trying to make Comment lines function, similar to VisualStudio. I will paste my code below questions.

1. How to position caret to the end of selection as in regular TextBox? If I programatically change selection, caret stays in original position, expected behavior is to change its position to selection end. I tried to call CaretPosition.MoveToPosition, but it resets selection.

2. How to scroll to caret position? Something like ScrollToCaret() in regular TextBox.

3. How to replace selected text? I did it somehow, but is there any better way? I have problem with that code related to next question. In regular TextBox, I can simply change selected text by txtSource.SelectedText = selText.

4. Why SyntaxEditor handles new lines as CR and not CRLF? We are on Windows, .NET, WinForms, I expected standard Windows new lines. I changed my CommentLines method to split lines by CR character only, but when I prepare new text by StringBuilder.AppendLine, it adds CRLF  to string of course, and when I try to set new selection by new Span created by old selection start and my string length, it selects more characters (if I select 3 lines, it appends 3 more LFs and then string.Length is longer than real span in SyntaxEditor).

So, how to handle selection replacement correctly? This is my code:

			var editor = radSyntaxEditor1.SyntaxEditorElement;

			// if empty selection, set selection to caret position
			if (editor.Selection.IsEmpty)
				editor.Selection.Select(editor.CaretPosition, editor.CaretPosition);

			// extend selection start
			editor.Selection.StartPosition.MoveToLineStart();

			// extend selection end - extend last line if empty or not on first char
			if (editor.Selection.IsEmpty || editor.Selection.EndPosition.ColumnNumber != 0)
				editor.Selection.EndPosition.MoveToLineEnd();

			// extend to start of next line if not on last line
			if (editor.Selection.EndPosition.LineNumber + 1 < editor.Document.CurrentSnapshot.LineCount)
			{
				editor.Selection.EndPosition.MoveLineDown();
				editor.Selection.EndPosition.MoveToLineStart();
			}

			// set caret to selection end
			//editor.CaretPosition.MoveToPosition(editor.Selection.EndPosition);

			// comment lines
			string selText = editor.Selection.GetSelectedText();
			string commentedText = CommentLines(selText);

			// if modified, replace selection
			bool modified = selText != commentedText;
			if (modified)
			{
				var span = editor.Selection.SelectedSpans.First();
				editor.Document.Replace(span, commentedText);
				editor.Selection.Select(new Span(span.Start, commentedText.Length));
			}

			radSyntaxEditor1.Refresh();

0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 24 Jun 2022, 08:53 AM
Hello, Marian,

My colleague, Dinko, is out of office this today so I will be assisting you with this case.

1.The SyntaxEditorElement.CaretPosition offers a convenient API for moving the caret wherever you need through the document. However, indeed, moving the caret position is expected to clear the selection. That is why if you want to make a selection and place the caret at the end of the selection, you can execute the following steps:
- Select the desired text and store the start/end selection position
- Move the caret to the selection's end. As a result the selection will be cleared. However, you will have stored the start/end selection
- Select again the desired portion of the text. 

The below code snippet shows what I mean which result is illustrated in the gif file: 
        private void radButton1_Click(object sender, EventArgs e)
        {
            var editor = radSyntaxEditor1.SyntaxEditorElement;

			// if empty selection, set selection to caret position
			if (editor.Selection.IsEmpty)
				editor.Selection.Select(editor.CaretPosition, editor.CaretPosition);

			// extend selection start
			editor.Selection.StartPosition.MoveToLineStart();

			// extend selection end - extend last line if empty or not on first char
			if (editor.Selection.IsEmpty || editor.Selection.EndPosition.ColumnNumber != 0)
				editor.Selection.EndPosition.MoveToLineEnd();

			// extend to start of next line if not on last line
			if (editor.Selection.EndPosition.LineNumber + 1 < editor.Document.CurrentSnapshot.LineCount)
			{
				editor.Selection.EndPosition.MoveLineDown();
				editor.Selection.EndPosition.MoveToLineStart();
			}
            CaretPosition start =new CaretPosition( this.radSyntaxEditor1.SyntaxEditorElement.Selection.StartPosition);
            CaretPosition end =new CaretPosition( this.radSyntaxEditor1.SyntaxEditorElement.Selection.EndPosition);
            this.radSyntaxEditor1.SyntaxEditorElement.CaretPosition.MoveToPosition(this.radSyntaxEditor1.SyntaxEditorElement.Selection.EndPosition);
            this.radSyntaxEditor1.SyntaxEditorElement.Selection.Select(start,end);

            this.radSyntaxEditor1.Focus();          
           
        }

2. When the caret position is moved, RadSyntaxEditor automatically scrolls to the caret position. Hence, if you use the above approach from 1. the view will be scrolled to the desired location.

3. Using the selection, you can replace it with any text you need:

            string selText = editor.Selection.GetSelectedText();
            string commentedText = selText.ToUpper(); 

            var span = editor.Selection.SelectedSpans.First();
            editor.Document.Replace(span, commentedText);
            editor.Selection.Select(new Span(span.Start, commentedText.Length));

4. I am not sure what is the exact implementation of the CommentLines method that you have. Could you please elaborate? I believe that the approach for replacing the selection in 3. would fit your requirements. Please give it a try and see whether you have any further questions regarding 4. In case you are still experiencing any further difficulties, it would be greatly appreciated if you can provide more details about the exact goal that you are trying to achieve. Thus, we would get better understanding of the precise case and provide further assistance.

I hope this information helps.

Regards,
Dess | Tech Support Engineer, Principal
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Marian
Top achievements
Rank 1
Iron
Iron
Iron
commented on 24 Jun 2022, 12:13 PM | edited

Hello, thanks for answers.

1. Ok, I can do it this way, it's not a problem. I asked only if there is a better solution. Because in regular TextBox setting selection also moves a caret, also if you select text by mouse it changes caret position.

2. Thanks, I haven't tried this.

3. Yes, I was just asking if there is better or more straightforward solution than this. Also my code was working after fixing CR/CRLF problem.

4. That was just question why you use only CR character for new line when we are on Windows, where CRLF is standard. I fixed it easily by replacing CRLF to CR before replacing back to SyntaxEditor. But personally I don't like converting CR/CRLF in each text interaction with SyntaxEditor. It's not a problem, but it doesn't look nice.

EDIT: Sorry, not CR only for new line, but LF only.

I am implementing "Comment lines" function as in VisualStudio, which comments or uncomments all selected lines:

CommentLines method just splits text to lines, adding // to each non-empty line. I fixed the problem by replacing CRLF to CR at the end of method. After this walkaround selecting new text works ok - editor.Selection.Select(new Span(span.Start, commentedText.Length)). Before, the problem was that commentedText.Length was longer than real text in SyntaxEditor, because SyntaxEditor discards LF character in CRLF.


		private string CommentLines(string text)
		{
			string[] lines = text.Split(new string[] { "\n" }, StringSplitOptions.None);

			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < lines.Length; i++)
			{
				string line = lines[i];
				if (line.Trim().Length > 0)
				{
					sb.Append("//");
					sb.Append(line);
				}
				if (i < lines.Length - 1)
					sb.AppendLine();
			}

			sb.Replace("\r\n", "\r");

			return sb.ToString();
		}

Marian
Top achievements
Rank 1
Iron
Iron
Iron
commented on 24 Jun 2022, 12:35 PM

And, now I have a working sample and I think I have all to upgrade my editor to SyntaxEditor.

Marian
Top achievements
Rank 1
Iron
Iron
Iron
commented on 24 Jun 2022, 09:16 PM

Hello, I has successfully migrated my editor to SyntaxEditor. Just one more question I haven't noticed before - regular TextBox has CanUndo property, which indicates Undo command is possible and I have used that property for enabling Undo button on toolbar. Is it also somewhere here?
0
Marian
Top achievements
Rank 1
Iron
Iron
Iron
answered on 25 Jun 2022, 01:23 PM | edited on 25 Jun 2022, 01:34 PM

Hello, I have found next few issues.

1. When zooming, something strange happens with row numbers and its margins, see animation:

2. When user make doubleclick, expected behavior is to select whole word behing cursor as in regular TextBox.  Is this missing in SyntaxEditor?

3. Scrolling by mouse wheel, it scrolls too many lines per mouse wheel step. I have found solution here in forum, but it was on other hand too few, so I multiplied that step by 3. But the best would be if you can modify SyntaxEditor to either make it settable or change it to standard way (3 lines per mouse wheel step). Also that small step doesn't seem to be exactly one line, is it related to changed font size?

4. Replace all function replaces it in whole file, not just in selection.

0
Dinko | Tech Support Engineer
Telerik team
answered on 27 Jun 2022, 11:35 AM

Hello Marian,

Let me go straight to your questions.

1. I have tested this behavior but wasn't able to reproduce it on my side. I have used the First Look example in our demos. May I ask you to share if you have specified different font for the RadSyntaxEditor? If yes, which one? If not, could it be possible to share a sample project which demonstrates this so that I can debug this on my side?