あなたは私のただ一つの希望だ。私はどこでも検索しましたが、これで私を助けることができるものは何も見つかりません.
Visual Studio (2010) 用の単純なコード マーキング プラグインを作成しました。強調表示するコードの一部を (Regex によって) 見つけ、見つかった一致から Spans を作成し、テキストと共にスクロールする Rectangle 装飾を (テキストの背景に) 作成します。これはすべて、view.LayoutChanged イベントの実装で行われます。それは正常に動作します...しかし...毎回ではありません! 場合によっては、マーカーがさまざまな距離 (主に上または下)だけ移動し、テキストがスクロールされている間、これらの不適切な位置を維持することがあります。なぜ、いつこれが起こるのかわかりません。私はこれらのいくつかのことだけを発見することができました:
- コードエディタウィンドウの垂直スクロールバーを非常に速く激しく上下にドラッグすることで、このバグを再現できます (いくつかのマーカーを正しい位置から移動します) (ただし、位置が修正されることもあります...)
- マーカーが配置されている行 (またはマークされたテキスト) を編集しても、マーカーの位置を修正することはできません。
- マークされたコードが配置されているコード ブロックの末尾の "}" を削除して復元することで、マーカーの位置を修正できます (これにより、コード ブロック全体が再フォーマットされます)。
- 位置が正しく計算されない場合 (view は WpfTextView クラス) 、view.ViewportTop は負になり、Geometry "g" (以下を参照) も負の Bounds.Top を取得します。(VS を別の VS に接続してブレークポイントを設定することでテストできます)
位置を計算してマーカーを作成するコードの一部を次に示します (LayoutChanged イベント)。
Geometry g = textViewLines.GetMarkerGeometry(span);
if (g != null)
{
GeometryDrawing drawing = new GeometryDrawing(_brush, _pen, g);
drawing.Freeze();
DrawingImage drawingImage = new DrawingImage(drawing);
drawingImage.Freeze();
Image image = new Image();
image.Source = drawingImage;
//Align the image with the top of the bounds of the text geometry
Canvas.SetLeft(image, g.Bounds.Left);
Canvas.SetTop(image, g.Bounds.Top);
//_layer.AddAdornment(AdornmentPositioningBehavior.TextRelative, span, null, image, null);
Rect rect = new Rect(g.Bounds.Location, g.Bounds.Size);
Rectangle marker = new Rectangle();
marker.Margin = new Thickness(rect.X - 3, rect.Y - 2, 0, 0);
marker.Width = rect.Width + 6; marker.Height = rect.Height + 4;
marker.Fill = new SolidColorBrush(mark);
marker.RadiusX = marker.RadiusY = 5;
marker.Stroke = new SolidColorBrush(color);
_layer.AddAdornment(AdornmentPositioningBehavior.TextRelative, span, null, marker, null);
}
これは基本的に装飾品を作成するための MSDN の例です。ここでは魔法を使っているわけではありません。
助けてください!