2013-10-11 8 views
11

入力ヒットテストでは、RenderTransformプロパティに大きなスケーリングファクタを持つPath要素で不正な結果が返されます。変換されたパスでヒットテストが正しく行われない

次のXAMLは、円で塗りつぶされたパスとHandカーソルを定義しています。下の画像に見られるよう

<Canvas Background="LightGray"> 
    <Path StrokeThickness="0" Fill="Blue" Cursor="Hand"> 
     <Path.Data> 
      <EllipseGeometry RadiusX=".5" RadiusY=".5" Center="1,1"/> 
     </Path.Data> 
     <Path.RenderTransform> 
      <ScaleTransform ScaleX="150" ScaleY="150"/> 
     </Path.RenderTransform> 
    </Path> 
</Canvas> 

その位置が形状外の方法であるが、Handカーソルが表示されます。大きなパスと小さいスケーリング

enter image description here

は期待通りに問題が消え、カーソルの動作要因。キャンバス上のマウスイベントハンドラでこの

private void Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
{ 
    var canvas = (UIElement)sender; 
    var hitElement = canvas.InputHitTest(e.GetPosition(canvas)); 
    Trace.TraceInformation("hitElement = {0}", hitElement); 
} 

のような明示的なヒットテストを実行

<Canvas Background="LightGray"> 
    <Path StrokeThickness="0" Fill="Blue" Cursor="Hand"> 
     <Path.Data> 
      <EllipseGeometry RadiusX="50" RadiusY="50" Center="100,100"/> 
     </Path.Data> 
     <Path.RenderTransform> 
      <ScaleTransform ScaleX="1.5" ScaleY="1.5"/> 
     </Path.RenderTransform> 
    </Path> 
</Canvas> 

enter image description here

は、同じ間違った結果を提供します。スケーリングされたパスの外側にマウスをクリックすると、パスがヒットエレメントとして返されます。

この問題はSilverlightには表示されません。


ここで問題となるのは、この動作の原因と回避方法です。 Path要素の元のサイズを単純に変更することはできないため、「大規模要素を使用しない」などの回答は役に立ちません。

現状の回避策は、RenderTransformでパスを変換するのではなく、(変換をGeometry.Transformプロパティに適用することによって)代わりにデータを変換することです。しかし、複雑な塗りつぶし(たとえば、ImageBrush)があるので、塗りつぶしブラシも変換する必要があります(変換を設定するだけでなく、ビューポートも設定する必要があります)。

また、実際の変換はスケーリングだけでなく、回転して平行移動するMatrixTransformです。


この問題は、他のジオメトリと追加の変換でも発生することに注意してください。たとえば、RectangleGeometryを使用して変形されたPathは、同様に正しくない動作を示します。

大規模な因子と誤:小さなスケールファクタで正しい

<Canvas Background="LightGray"> 
    <Path StrokeThickness="0" Fill="Blue" Cursor="Hand"> 
     <Path.Data> 
      <RectangleGeometry Rect=".5,.5,1,1"/> 
     </Path.Data> 
     <Path.RenderTransform> 
      <TransformGroup> 
       <ScaleTransform ScaleX="150" ScaleY="150"/> 
       <RotateTransform Angle="45" CenterX="150" CenterY="150"/> 
       <TranslateTransform X="100"/> 
      </TransformGroup> 
     </Path.RenderTransform> 
    </Path> 
</Canvas> 

enter image description here

<Canvas Background="LightGray"> 
    <Path StrokeThickness="0" Fill="Blue" Cursor="Hand"> 
     <Path.Data> 
      <RectangleGeometry Rect="50,50,100,100"/> 
     </Path.Data> 
     <Path.RenderTransform> 
      <TransformGroup> 
       <ScaleTransform ScaleX="1.5" ScaleY="1.5"/> 
       <RotateTransform Angle="45" CenterX="150" CenterY="150"/> 
       <TranslateTransform X="100"/> 
      </TransformGroup> 
     </Path.RenderTransform> 
    </Path> 
</Canvas> 

enter image description here

+0

ソリューション:*大規模な因子を使用していません*。ナー、冗談だよ。 'RenderTranform'を' LayoutTransform'に変更すると起こりますか? –

+0

既にLayoutTransformはオプションではありませんが、これを試しました。とにかく、それはLayoutTransformでも同じように動作します。 – Clemens

+0

'Path。[Render | Layout] Transform'の代わりに' RectangleGeometry.Transform'を使うことを考えましたか?あなたは、ジオメトリ自体へのアクセス権を持っているので、あなたはすでに変換されたジオメトリをレンダリングするためにあなたの形状を有することができ、その後、ヒットテストをより自然にする必要があります。 – heltonbiker

答えて

3

答えよりも拡張されたコメントの多く:

これは奇妙な動作のようですが、私はいくつかの遊びを持っていましたPathsと、Geometry.GetWidenedPathGeometryを使って、データ自体に少し異なるスケーリング効果を適用しようとしましたが、それほど遠くには達しませんでした。

問題の根本的な原因は、ヒット検出の許容範囲がWPFで選択されているようですが、Brendan ClarkのMSDNに関する類似の質問に対する2つの回答があります。

本質的に使用されるヒットテストの許容誤差は、ジオメトリ自体の基本サイズではなく、レンダリングされた/形質転換されたサイズに由来する絶対値であると思われます。 (あなたが見つけてきたように)それはあなたが小さな維持している小さい、または実際に小さな形状を作っている、大きな形状の罰金だながらだから、それは小さな形状がスケールアップされたとき、非常に不正確になるが開始されます。

I.e.小さな形状の大きさに小さなヒットテストの許容相対は罰金ですが、形状や寛容の両方がスケールアップを取得する場合、それは恐ろしい見え始めます。

1つのスレッドで提案された解決策は、あなたが必要とmaxiumumサイズまで形状を拡大し、あなたは(あなたのためのソリューションではないです)彼らは小さいしたいときにそれらをスケールダウンすることでした。 Ew。

あなたには、いくつかの変換で立ち往生する可能性があるように見えます。私はもっ​​と良いものを考え出すことができるかどうか試してみる。私が見ていた

リンク:

http://social.msdn.microsoft.com/Forums/vstudio/en-US/8708e340-f734-4cf4-b91d-28b49fee2b72/hittest-is-buggy-not-accurate-for-transformed-scaled-etc-visuals?forum=wpf

http://social.msdn.microsoft.com/Forums/vstudio/en-US/b307676b-d8b2-4af0-9f6f-1e150eed97ba/hittesting-with-a-scaled-path-doesnt-work?forum=wpf

+0

この説明とリンクをご提供いただき、ありがとうございます。それが私が探していたものです。 – Clemens

+1

うれしかった= D – Chris

関連する問題