0

あなたは私のただ一つの希望だ。私はどこでも検索しましたが、これで私を助けることができるものは何も見つかりません.

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 の例です。ここでは魔法を使っているわけではありません。

助けてください!

4

2 に答える 2

0

私も同じ問題を抱えていました。使用する場合

_layer.AddAdornment(AdornmentPositioningBehavior.TextRelative,...);

何度も挿入する必要があります

Canvas.SetLeft(image, g.Bounds.Left);
Canvas.SetTop(image, g.Bounds.Top);

毎回前に。

于 2013-11-27T17:30:20.017 に答える
0

私はちょうど一日を同様の問題に費やしました。

スパン移動の問題以外にも、文書化されていないコーナー ケースが多数あります。さらに悪いことに、証明されているように見えるソリューションは、決して VS バージョンで壊れる傾向があります (特に、roslyn と VS2015 から)。私のお気に入りは次のとおりです。複数行のコメント内で複数回エンターを押すと、装飾が削除されることがありました。陽気な!

したがって、唯一の有効なアプローチは次のとおりです。VS エディターの裏をかこうとしないでください。

代わりに、roslyn の からコードを借りてくださいAdornmentManager<T>。私が再発明しなければならなかった多くのハックが含まれており、さらに私が今まで疑っていなかったハックが含まれていますが、うまくいきます. あなたがする必要があるのは、以下のコードを置き換えることだけです

// add the visual to the adornment layer.

あなたのものと一緒に(その部分は、オーバーライド可能なメソッドにリファクタリングするのに適した候補です)。

PS私は少し遅れていることを知っています:)これが別の貧しい魂の時間を節約できることを願っています.

于 2015-10-19T18:27:35.813 に答える