diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/Caret.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/Caret.cs index 930edf8140..5e9ecfc470 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/Caret.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/Caret.cs @@ -298,6 +298,11 @@ namespace ICSharpCode.AvalonEdit.Editing lineBottom - lineTop); } + /// + /// Minimum distance of the caret to the view border. + /// + internal const double MinimumDistanceToViewBorder = 30; + /// /// Scrolls the text view so that the caret is visible. /// @@ -306,7 +311,7 @@ namespace ICSharpCode.AvalonEdit.Editing if (textView != null) { VisualLine visualLine = textView.GetOrConstructVisualLine(textView.Document.GetLineByNumber(position.Line)); Rect caretRectangle = CalcCaretRectangle(visualLine); - caretRectangle.Inflate(30, 30); // leave at least 30 pixels distance to the view border + caretRectangle.Inflate(MinimumDistanceToViewBorder, MinimumDistanceToViewBorder); textView.MakeVisible(caretRectangle); } } diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditor.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditor.cs index d9c6898cb1..95b0eb0c2b 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditor.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditor.cs @@ -20,6 +20,7 @@ using ICSharpCode.AvalonEdit.Editing; using ICSharpCode.AvalonEdit.Highlighting; using ICSharpCode.AvalonEdit.Rendering; using ICSharpCode.AvalonEdit.Utils; +using System.Windows.Threading; namespace ICSharpCode.AvalonEdit { @@ -880,5 +881,30 @@ namespace ICSharpCode.AvalonEdit { return textArea.GetService(serviceType); } + + /// + /// Scrolls to the specified line/column. + /// This method requires that the TextEditor was already assigned a size (WPF layout must have run prior). + /// + public void ScrollTo(int line, int column) + { + const double MinimumScrollPercentage = 0.3; + + if (scrollViewer != null) { + Point p = textArea.TextView.GetVisualPosition(new TextViewPosition(line, column), VisualYPosition.LineMiddle); + double verticalPos = p.Y - scrollViewer.ViewportHeight / 2; + if (Math.Abs(verticalPos - scrollViewer.VerticalOffset) > MinimumScrollPercentage * scrollViewer.ViewportHeight) { + scrollViewer.ScrollToVerticalOffset(Math.Max(0, verticalPos)); + } + if (p.X > scrollViewer.ViewportWidth - Caret.MinimumDistanceToViewBorder * 2) { + double horizontalPos = Math.Max(0, p.X - scrollViewer.ViewportWidth / 2); + if (Math.Abs(horizontalPos - scrollViewer.HorizontalOffset) > MinimumScrollPercentage * scrollViewer.ViewportWidth) { + scrollViewer.ScrollToHorizontalOffset(horizontalPos); + } + } else { + scrollViewer.ScrollToHorizontalOffset(0); + } + } + } } } diff --git a/src/Main/Base/Project/Src/Editor/AvalonEdit/AvalonEditTextEditorAdapter.cs b/src/Main/Base/Project/Src/Editor/AvalonEdit/AvalonEditTextEditorAdapter.cs index be39402db4..8f29cf385a 100644 --- a/src/Main/Base/Project/Src/Editor/AvalonEdit/AvalonEditTextEditorAdapter.cs +++ b/src/Main/Base/Project/Src/Editor/AvalonEdit/AvalonEditTextEditorAdapter.cs @@ -13,6 +13,7 @@ using System.Windows.Input; using ICSharpCode.AvalonEdit.Editing; using ICSharpCode.SharpDevelop.Editor.CodeCompletion; +using System.Windows.Threading; namespace ICSharpCode.SharpDevelop.Editor.AvalonEdit { @@ -194,7 +195,15 @@ namespace ICSharpCode.SharpDevelop.Editor.AvalonEdit { textEditor.TextArea.Selection = Selection.Empty; textEditor.TextArea.Caret.Position = new TextViewPosition(line, column); - textEditor.TextArea.Caret.BringCaretToView(); + if (textEditor.ActualHeight > 0) { + textEditor.ScrollTo(line, column); + } else { + // we have to delay the scrolling if the text editor is not yet loaded + textEditor.Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action( + delegate { + textEditor.ScrollTo(line, column); + })); + } } public virtual IInsightWindow ActiveInsightWindow {