Browse Source

Don't crash when InlineUIElementGenerator's anchor is deleted.

Fix focus when inline UIElement is removed from TextView.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@5261 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
Daniel Grunwald 16 years ago
parent
commit
a6d67cfa53
  1. 6
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/AvalonEditEditorUIService.cs
  2. 3
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/InlineUIElementGenerator.cs
  3. 26
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextLayer.cs

6
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/AvalonEditEditorUIService.cs

@ -13,7 +13,7 @@ using ICSharpCode.SharpDevelop.Editor;
namespace ICSharpCode.AvalonEdit.AddIn namespace ICSharpCode.AvalonEdit.AddIn
{ {
public class AvalonEditEditorUIService : IEditorUIService sealed class AvalonEditEditorUIService : IEditorUIService
{ {
TextView textView; TextView textView;
@ -24,6 +24,10 @@ namespace ICSharpCode.AvalonEdit.AddIn
public IInlineUIElement CreateInlineUIElement(ITextAnchor position, UIElement element) public IInlineUIElement CreateInlineUIElement(ITextAnchor position, UIElement element)
{ {
if (position == null)
throw new ArgumentNullException("position");
if (element == null)
throw new ArgumentNullException("element");
InlineUIElementGenerator inline = new InlineUIElementGenerator(textView, element, position); InlineUIElementGenerator inline = new InlineUIElementGenerator(textView, element, position);
this.textView.ElementGenerators.Add(inline); this.textView.ElementGenerators.Add(inline);
return inline; return inline;

3
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/InlineUIElementGenerator.cs

@ -13,7 +13,7 @@ using ICSharpCode.SharpDevelop.Editor;
namespace ICSharpCode.AvalonEdit.AddIn namespace ICSharpCode.AvalonEdit.AddIn
{ {
public class InlineUIElementGenerator : VisualLineElementGenerator, IInlineUIElement sealed class InlineUIElementGenerator : VisualLineElementGenerator, IInlineUIElement
{ {
ITextAnchor anchor; ITextAnchor anchor;
UIElement element; UIElement element;
@ -24,6 +24,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
this.textView = textView; this.textView = textView;
this.element = element; this.element = element;
this.anchor = anchor; this.anchor = anchor;
anchor.Deleted += delegate { Remove(); };
} }
public override int GetFirstInterestedOffset(int startOffset) public override int GetFirstInterestedOffset(int startOffset)

26
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextLayer.cs

@ -8,6 +8,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Windows; using System.Windows;
using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
namespace ICSharpCode.AvalonEdit.Rendering namespace ICSharpCode.AvalonEdit.Rendering
@ -67,14 +68,32 @@ namespace ICSharpCode.AvalonEdit.Rendering
inlineObjects.RemoveAll( inlineObjects.RemoveAll(
ior => { ior => {
if (visualLinesWithOutstandingInlineObjects.Contains(ior.VisualLine)) { if (visualLinesWithOutstandingInlineObjects.Contains(ior.VisualLine)) {
ior.VisualLine = null; RemoveInlineObjectRun(ior);
RemoveVisualChild(ior.Element);
return true; return true;
} }
return false; return false;
}); });
visualLinesWithOutstandingInlineObjects.Clear(); visualLinesWithOutstandingInlineObjects.Clear();
} }
// Remove InlineObjectRun.Element from TextLayer.
// Caller of RemoveInlineObjectRun will remove it from inlineObjects collection.
void RemoveInlineObjectRun(InlineObjectRun ior)
{
if (ior.Element.IsKeyboardFocusWithin) {
// When the inline element that has the focus is removed, WPF will reset the
// focus to the main window without raising appropriate LostKeyboardFocus events.
// To work around this, we manually set focus to the next focusable parent.
UIElement element = textView;
while (element != null && !element.Focusable) {
element = VisualTreeHelper.GetParent(element) as UIElement;
}
if (element != null)
Keyboard.Focus(element);
}
ior.VisualLine = null;
RemoveVisualChild(ior.Element);
}
/// <summary> /// <summary>
/// Removes the inline object that displays the specified UIElement. /// Removes the inline object that displays the specified UIElement.
@ -84,8 +103,7 @@ namespace ICSharpCode.AvalonEdit.Rendering
inlineObjects.RemoveAll( inlineObjects.RemoveAll(
ior => { ior => {
if (ior.Element == element) { if (ior.Element == element) {
ior.VisualLine = null; RemoveInlineObjectRun(ior);
RemoveVisualChild(ior.Element);
return true; return true;
} }
return false; return false;

Loading…
Cancel
Save