Posted 12 years ago
by \アッカリーン/
Version: 12.2.0571
Platform: .NET 4.5
Environment: Windows 8 (64-bit)

Hi there,
After copying code directly out of one of the sample projects, the Syntax Editor does not update properly after switch out to a new language. The adornments do not stay properly aligned with the text, and fall off their mark when scrolling.
I wrote a simple sample project to demonstrate the problem. Please try running it and scroll normally, and then try scrolling after pressing the "Switch Language" button.
Please let me know if this is indeed a bug, or if there is something I'm missing that needs to be updated.
Thank you-
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:syntaxeditor="http://schemas.actiprosoftware.com/winfx/xaml/syntaxeditor" x:Class="SyntaxTest.MainWindow"
Title="MainWindow" Height="600" Width="800">
<DockPanel LastChildFill="True">
<Button Width="100" Click="Switch_Language" Content="Switch Language" />
<syntaxeditor:SyntaxEditor Name="SyntaxEditor" />
</DockPanel>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Text.RegularExpressions;
using ActiproSoftware.Text;
using ActiproSoftware.Text.Implementation;
using ActiproSoftware.Text.Tagging;
using ActiproSoftware.Text.Tagging.Implementation;
using ActiproSoftware.Windows.Media;
using ActiproSoftware.Text.Utility;
using ActiproSoftware.Windows.Controls.SyntaxEditor;
using ActiproSoftware.Windows.Controls.SyntaxEditor.Adornments;
using ActiproSoftware.Windows.Controls.SyntaxEditor.Adornments.Implementation;
using ActiproSoftware.Windows.Controls.SyntaxEditor.Highlighting;
namespace SyntaxTest
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
SyntaxEditor.Document.SetText(Enumerable.Range(0, 200).Select(a => a % 5 == 0 ? "#FF00FF\t#FF0000\r\n" : "\r\n").Aggregate((a, b) => a + b));
SyntaxEditor.Document.Language = new MyLanguage();
}
private void Switch_Language(object sender, RoutedEventArgs e)
{
SyntaxEditor.Document.Language = new MyLanguage();
}
}
public class MyLanguage : SyntaxLanguage
{
public MyLanguage() : base("MyLanguage")
{
this.RegisterService(new CodeDocumentTaggerProvider<ColorPreviewTagger>(typeof(ColorPreviewTagger)));
this.RegisterService(new AdornmentManagerProvider<ColorPreviewAdornmentManager>(typeof(ColorPreviewAdornmentManager)));
}
}
public class ColorPreviewTag : ITag
{
public Color Color { get; set; }
}
public class ColorPreviewTagger : TaggerBase<ColorPreviewTag>
{
public ColorPreviewTagger(ICodeDocument document) : base("ColorPreview", null, document, true) { }
public override IEnumerable<TagSnapshotRange<ColorPreviewTag>> GetTags(NormalizedTextSnapshotRangeCollection snapshotRanges, object parameter)
{
if (snapshotRanges != null)
{
foreach (TextSnapshotRange snapshotRange in snapshotRanges)
{
string text = snapshotRange.Text;
MatchCollection matches = Regex.Matches(text, @"\#([a-f0-9]{6}|[a-f0-9]{3})\b", RegexOptions.IgnoreCase);
if (matches.Count > 0)
{
foreach (Match match in matches)
{
ColorPreviewTag tag = new ColorPreviewTag();
tag.Color = UIColor.FromWebColor(match.Value).ToColor();
yield return new TagSnapshotRange<ColorPreviewTag>(
TextSnapshotRange.FromSpan(snapshotRange.Snapshot, snapshotRange.StartOffset + match.Index, match.Length), tag);
}
}
}
}
}
}
public class ColorPreviewAdornmentManager : DecorationAdornmentManagerBase<IEditorView, ColorPreviewTag>
{
private static AdornmentLayerDefinition layerDefinition =
new AdornmentLayerDefinition("ColorPreview", new Ordering(AdornmentLayerDefinitions.TextForeground.Key, OrderPlacement.After));
public ColorPreviewAdornmentManager(IEditorView view) : base(view, layerDefinition) { }
private static UIElement CreateDecorator(double width, Color color)
{
Rectangle rect = new Rectangle() { Width = width, Height = 3, Fill = new SolidColorBrush(color) };
rect.Fill.Freeze();
return rect;
}
protected override void AddAdornment(ITextViewLine viewLine, TagSnapshotRange<ColorPreviewTag> tagRange, TextBounds bounds)
{
UIElement element = ColorPreviewAdornmentManager.CreateDecorator(bounds.Width, tagRange.Tag.Color);
Point location = new Point(Math.Round(bounds.Left), bounds.Bottom - 2);
this.AdornmentLayer.AddAdornment(element, location, viewLine, tagRange.SnapshotRange, TextRangeTrackingModes.Default, null);
}
protected override void OnClosed()
{
this.AdornmentLayer.RemoveAllAdornments();
}
}
}