前提・実現したいこと
WPF(C#)で2D描画ソフトを作っています。
CanvasにGridを配置し、HitTestでGridを選択したいのですが
Canvas上のGridは見かけ上の位置しか変更できず
もともとの位置((x,y)=(0,0))でしか、HitTestを行えません。
変更後の位置でHitTestをあて、rowとcolumnの情報を取得するにはどうしたらよいでしょうか!?
試したこと
C#
1Grid myGrid = new Grid(); 2myCanvas.Children.Add(myGrid); 3//見かけしか変化しない(HitTest位置が変化しない) 4myGrid.RenderTransform = new TranslateTransform(X1,Y1); 5//見かけしか変化しない(HitTest位置が変化しない) 6myGrid.Margin=new Margin(X1,Y1,0,0); 7//見かけしか変化しない(HitTest位置が変化しない) 8Canvas.SetLeft(myGrid,X1); 9Canvas.SetTop(myGrid,Y1); 10//無効(LayoutTransformのMSDより) 11myGrid.LayoutTransform= new TranslateTransform(X1, Y1); 12
Brushを透明にしたSystem.Windows.Shapes.Path に同じ形の図形(Grid
場合は四角形)を指定し、見かけ上のGridと同じ位置に配置することで
HitTestを当てることは可能です。ただ、この方法だとGridのrowとcolumnを
取得するのが非常に面倒です。
よろしくお願いいたします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答2件
0
解決されたようですが、第三者目線ではさっぱり意味が分かんないですね(私の頭が悪いだけかもしれませんが^^;
そもそもHitTest
はどういう意味で使っていますか?
UIElement.InputHitTest(Point) メソッド (System.Windows) | Microsoft Docs
や、
VisualTreeHelper.HitTest メソッド (System.Windows.Media) | Microsoft Docs
のことですか?
それともマウスクリック等のことですか?
Canvas上のGridは見かけ上の位置しか変更できず
もともとの位置((x,y)=(0,0))でしか、HitTestを行えません。
そんなことないと思いますけど、どう確認しましたか?
rowとcolumnの情報を取得するにはどうしたらよいでしょうか!?
「HitTest
でGrid
を選択したい」(取得したい?)と矛盾するというか、Grid
の中に入っている何かのHitTest
から、Row
・Column
を取得ならわかります。
しかしGrid
自体を取ったところで、その位置のRow
・Column
を手軽に出す方法はないと思うのですが(計算することはできるでしょうけど)
//無効(LayoutTransformのMSDより)
これのことですね。
However, LayoutTransform ignores TranslateTransform operations.
FrameworkElement.LayoutTransform Property (System.Windows) | Microsoft Docs
なにか質問に書かれていない、前提条件があるのでしょうか?
(コンパイル可能な)簡単なサンプルを提示いただくと、他人にとっても役に立つ質問になるかもしれません。
xml
1<Window 2 x:Class="Questions369551.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 Width="500" 6 Height="600"> 7 <Grid> 8 <Grid.RowDefinitions> 9 <RowDefinition Height="2*" /> 10 <RowDefinition Height="3*" /> 11 </Grid.RowDefinitions> 12 <GroupBox Header="Canvas in Grid 移動テスト"> 13 <Canvas 14 x:Name="canvas1" 15 Background="White" 16 MouseLeftButtonDown="Canvas_MouseLeftButtonDown"> 17 <Grid 18 x:Name="grid1" 19 Width="100" 20 Height="100" 21 Background="Blue" /> 22 <Grid 23 x:Name="grid2" 24 Width="100" 25 Height="100" 26 Background="Blue"> 27 <Grid.RenderTransform> 28 <TranslateTransform X="100" Y="100" /> 29 </Grid.RenderTransform> 30 </Grid> 31 <Grid 32 x:Name="grid3" 33 Width="100" 34 Height="100" 35 Margin="200,0,0,0" 36 Background="Blue" /> 37 <Grid 38 x:Name="grid4" 39 Canvas.Left="300" 40 Canvas.Top="100" 41 Width="100" 42 Height="100" 43 Background="Blue" /> 44 </Canvas> 45 </GroupBox> 46 47 <GroupBox Grid.Row="1" Header="Shape HitTest テスト"> 48 <Canvas x:Name="canvas2" MouseLeftButtonDown="Canvas_MouseLeftButtonDown"> 49 <Grid 50 Canvas.Left="30" 51 Canvas.Top="30" 52 Width="200" 53 Height="200" 54 Margin="20,20,0,0" 55 ShowGridLines="True"> 56 <Grid.RenderTransform> 57 <TranslateTransform X="10" Y="10" /> 58 </Grid.RenderTransform> 59 <Grid.RowDefinitions> 60 <RowDefinition /> 61 <RowDefinition /> 62 </Grid.RowDefinitions> 63 <Grid.ColumnDefinitions> 64 <ColumnDefinition /> 65 <ColumnDefinition /> 66 </Grid.ColumnDefinitions> 67 <Rectangle 68 x:Name="rectangle" 69 Grid.Column="1" 70 Fill="Green" /> 71 <Ellipse 72 x:Name="ellipse" 73 Grid.Row="1" 74 Fill="HotPink" /> 75 <Polygon 76 x:Name="polygon" 77 Grid.Row="1" 78 Grid.Column="1" 79 Fill="Orange" 80 Points="0,100 100,100 50,0" /> 81 </Grid> 82 </Canvas> 83 </GroupBox> 84 </Grid> 85</Window>
cs
1using System; 2using System.Diagnostics; 3using System.Windows; 4using System.Windows.Controls; 5using System.Windows.Input; 6using System.Windows.Media; 7 8namespace Questions369551 9{ 10 public partial class MainWindow : Window 11 { 12 public MainWindow() => InitializeComponent(); 13 14 private void Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 15 { 16 if (sender is Canvas canvas) 17 { 18 var p = e.GetPosition(canvas); 19 if (VisualTreeHelper.HitTest(canvas, p)?.VisualHit is FrameworkElement element) 20 { 21 var r = Grid.GetRow(element); 22 var c = Grid.GetColumn(element); 23 Debug.WriteLine($"{DateTime.Now:HH:mm:ss.fff} {element.Name} Row:{r} Column:{c}"); 24 } 25 } 26 } 27 } 28}
投稿2021/11/16 09:47
編集2023/07/29 08:36総合スコア10022
0
自己解決
既読下さりありがとうございました。
望んでいたことはできませんでしたが、代替案で解決しました。
C#
1//見えないブラシを作成 2SolidColorBrush MySolidColorBrush = new SolidColorBrush(); 3MySolidColorBrush.Color = Color.FromArgb(0, 0, 0, 0); 4 5//四角形を沢山作る(ここでは1つしか作っていない) 6GeometryGroup geometryGroup = new GeometryGroup(); 7RectangleGeometry geometry = new RectangleGeometry(); 8geometry.Rect = new Rect(X, Y,Width,Height); 9geometryGroup.Children.Add(geometry); 10//Path.Dataに当てはめる 11myPath.Data=geometryGroup; 12myPath.Fill=MySolidColorBrush;
でGridのマス分の見えない四角形を生成して,ヒットテストに当てて
事なきを得ました。
Gridに追加するcontrolとGeometryGroupに追加するRectangleGeometryの
順番を同じにしたので、indexを取得してrowとcolumnを断定しました。
ヒットテストを行う際は
C#
1//パスの追加 2MyCanvas.Children.Add(myPath); 3//これをしないとヒットテスト対象にならない。 4MyCanvas.UpdateLayout();
をお忘れなく。
投稿2021/11/16 08:23
総合スコア-1
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。