6

私は、ジオメトリがこの構文で記述されているパスをラップするDrawingVisual要素を持っています:

"m106,59.3c0-1.98,0,0-4.95,0.989-3.96,0.989-13.8,3.96-20.8,4.95-6.92,0-14.8-3.96-17.8-3.96-1.98,2.97,3.96,10.9,7.91, 13.8,2.97,1.98,9.89,3.96,14.8,3.96,4.95-0.989,10.9-2.97,13.8-6.92,2.97-2.97,5.93-10.9,6.92-12.9z"

ビジュアルをレンダリングするには、ヒット テスト機能を提供する MyCanvas クラスを使用します。

public class MyCanvas : Panel
{
   public List<Visual> Visuals = new List<Visual>();
   private List<DrawingVisual> Hits = new List<DrawingVisual>();

   public void AddVisual(Visual Visual)
   {
       this.Visuals.Add(Visual);
       base.AddVisualChild(Visual);
       base.AddLogicalChild(Visual);
   }

   public List<DrawingVisual> GetVisuals(Geometry Region)
   {
       GeometryHitTestParameters Parameters = new GeometryHitTestParameters(Region);
       this.Hits.Clear();
       HitTestResultCallback Callback = new HitTestResultCallback(this.HitTestCallBack);
       VisualTreeHelper.HitTest(this, null, Callback, Parameters);

       return this.Hits;
   }

   private HitTestResultBehavior HitTestCallBack(HitTestResult Result)
   {
        GeometryHitTestResult GeometryRes = (GeometryHitTestResult)Result;
        DrawingVisual DVisual = Result.VisualHit as DrawingVisual;

        if (DVisual != null && GeometryRes.IntersectionDetail == IntersectionDetail.FullyInside) 
            this.Hits.Add(DVisual);     

       return HitTestResultBehavior.Continue;
   }

   protected override Visual GetVisualChild(int Index)
   { return this.Visuals[Index]; }

   protected override int VisualChildrenCount {
        get { return this.Visuals.Count; }
   }
}

(赤) パスを描画すると、結果は次のようになります。

グリッド セルのサイズは 50x50 です。たとえば、この地域でビジュアルを取得しようとしています。

MyCanvas my_canvas = new MyCanvas();
RectangleGeometry MyRegion = new RectangleGeometry(new Rect(50, 50, 250, 250));
DrawingVisual MyPath = new DrawingVisual();

using (DrawingContext context = MyPath.RenderOpen()) {
   context.PushTransform(new TranslateTransform(50, 50));
   context.PushTransform(new ScaleTransform(2, 2));
   context.DrawGeometry(Brushes.Red, new Pen(), MyGeometry);
}

my_canvas.AddVisual(MyPath);
List<DrawingVisual> result = my_canvas.GetVisuals(MyRegion);

しかし、MyPath が結果にないのはなぜですか? ヒットテストを適切に行うにはどうすればよいですか? ありがとう。

4

1 に答える 1

5

ヒット テストでは、逆の順序で変換が適用された形状の位置が考慮されているようです。これは、なぜ私のパスが交差しているだけで、メソッドの引数の内部で完全に交差していないのかを説明します.RectangleGeometryMyCanvas.GetVisuals

より良い応答を待って、ヒットテストではないメソッドを使用してヒットテストを実装しました。現在はクラスの一部ですMyCanvas

public List<DrawingVisual> GetVisuals(Rect Area)
{
   this.Hits.Clear();

   foreach (DrawingVisual DVisual in this.Visuals) {
       if (Area.Contains(DVisual.DescendantBounds))
           this.Hits.Add(DVisual);
   }

   return this.Hits;
}

編集:

Mike Danes (MSDN フォーラムのモデレーター) がこのスレッドで説明しているように:

「これがジオメトリ ヒット テストのバグである可能性は本当にありますか?」

これはバグだと99%確信しています。描画とヒット テストでは、同じ変換順序を使用する必要があります。これが TransformGroup で正しく機能する理由は、この方法では描画コンテキストで 1 つの変換のみをプッシュし、ヒット テストの描画コンテキストで誤った乗算順序が回避されるためです。これは、TranformGroup で使用される順序がプッシュ順序と異なるという事実とは関係がないことに注意してください。

于 2012-05-05T10:34:02.193 に答える