質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

0回答

3185閲覧

【WPF】C# Rectangle移動後の座標を取得したい

退会済みユーザー

退会済みユーザー

総合スコア0

canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2021/06/21 06:09

編集2021/06/22 02:37

前提・実現したいこと

色々なサイトを確認し、利用させて頂いてます。

たくさんあるのですが、手詰まり状態で困っています。
3日調べましたが、いい方法は見つかりませんでした。

・Rectangle移動後の座標、Canvasの左上を基準としたTop,Leftの値
⇒Canvas.GetLeft、Canvas.GetTopでは取得できませんでした。
RenderTransformの値だからだと思います。
MouseUpの時に現在位置を取得し設定して、RenderTransformを消したいです。

できたら、以下の内容もアドバイスがあれば伺いたいです。
・Rectangelの端をクリックし、ドラッグ移動でRectangleを拡大したい
⇒今のドラッグ移動のコードを一部追加したりすれば
Rectangleを左上座標固定して拡大することは出来そうだと思っています。
カーソルアイコンでの判定をしようと思っており、
これについてはまだ色々検証中です。

 

該当のソースコード

xaml

1 <Canvas Name="MyCanvas"> 2 <Rectangle x:Name="Rectan" Width="100" Height="100" Fill="Transparent" StrokeThickness="3" Stroke="Red"></Rectangle> 3 </Canvas>

C#

1 2 public PicView() 3 { 4 InitializeComponent(); 5 this.Top = 0;//ウィンドウ自体を移動 6 this.Left = 0;//ウィンドウ自体を移動 7 RectangleEvent(); 8 } 9 10 public void RectangleEvent() { 11 //色や線の太さなどは、後々動的に変更させる 12 Rectan.MouseLeftButtonDown += Rect_MouseLeftButtonDown; 13 Rectan.MouseEnter += Rect_MouseEnter; 14 Rectan.MouseLeave += Rect_Leave; 15 Rectan.MouseLeftButtonUp += Rect_MouseLeftButtonUp; 16 Rectan.MouseMove += Rect_MouseMove; 17 } 18 19 // マウス押下中フラグ 20 private bool _isMouseDown; 21 // マウスの移動が開始されたときの座標 22 private Point _startPoint; 23 // マウスの現在位置座標 24 private Point _currentPoint; 25 26 void Rect_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 27 { 28 // フラグを"マウス押下中"にする 29 _isMouseDown = true; 30 31 Mouse.OverrideCursor = Cursors.SizeAll; 32 Console.WriteLine("Cursors.Arrow!"); 33 _startPoint = e.GetPosition(MyCanvas); 34 Console.WriteLine(e.GetPosition(sender as Rectangle)); 35 // イベントを処理済みとする(当イベントがこの先伝搬されるのを止めるため) 36 e.Handled = true; 37 } 38 39 // マウス左ボタン解放イベントのハンドラ 40 private void Rect_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) 41 { 42 // マウス押下中フラグを落とす 43 _isMouseDown = false; 44 e.Handled = true; 45 } 46 private void Rect_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e) 47 { 48 (sender as Rectangle).Fill = new SolidColorBrush(Colors.Yellow); 49 Mouse.OverrideCursor = Cursors.SizeNWSE;//拡大アイコン 50 Console.WriteLine("マウスIN:" + e.GetPosition(sender as Rectangle)); 51 52 } 53 54 // マウス移動イベントのイベントハンドラ 55 private void Rect_MouseMove(object sender, MouseEventArgs e) 56 { 57 58 var rec = sender as Rectangle; 59 // マウス押下中でなければドラッグ操作ではないのでメソッドを抜ける 60 if (!_isMouseDown) 61 { 62 return; 63 } 64 65 //if (Mouse.OverrideCursor ==Cursors.SizeNWSE) { 66 //} 67 68 // マウスの現在位置座標を取得(MyCanvasからの相対位置) 69 _currentPoint = e.GetPosition(MyCanvas); 70 71 //移動開始点と現在位置の差から、MouseMoveイベント1回分の移動量を算出 72 double offsetX = _currentPoint.X - _startPoint.X; 73 double offsetY = _currentPoint.Y - _startPoint.Y; 74 75 // 動かす対象の図形からMatrixオブジェクトを取得 76 // このMatrixオブジェクトを用いて図形を描画上移動させる 77 Matrix matrix = ((MatrixTransform)(sender as Rectangle).RenderTransform).Matrix; 78 // TranslateメソッドにX方向とY方向の移動量を渡し、移動後の状態を計算 79 matrix.Translate(offsetX, offsetY); 80 // 移動後の状態を計算したMatrixオブジェクトを描画に反映する 81 (sender as Rectangle).RenderTransform = new MatrixTransform(matrix); 82 83 // 移動開始点を現在位置で更新する 84 // (今回の現在位置が次回のMouseMoveイベントハンドラで使われる移動開始点となる) 85 _startPoint = _currentPoint; 86 e.Handled = true; 87 } 88 private void Rect_Leave(object sender, System.Windows.Input.MouseEventArgs e) 89 { 90 (sender as Rectangle).Fill = Brushes.Transparent;//透明化 91 92 Mouse.OverrideCursor = Cursors.Arrow;//通常アイコン 93 94 _isMouseDown = false; 95 e.Handled = true; 96 } 97

試したこと

C#

1 Canvas.GetLeft(this.Rectan); 2 Canvas.GetTop(this.Rectan);

上記では、初期値が表示されるだけでした。
RenderTransformでRectangleを移動しているからだと思います。
MouseUpの時に現在位置を取得し設定し直して、
RenderTransformを消したいです。

試したこと 6/22 10:28

色々と検証を重ね、
いい方法とは思えませんが、
RectangleCreateにて、Rectangleを削除し作り直すようにしました。
(Eventのものは削除しました。

C#

1RectangleCreate(){ 2 var type = typeof(Brushes); 3 Rectangle Rectan = new Rectangle();//Rectangle新規作成 4 Rectan.Name = "Rectan";//Rectanという名前にする 5 Rectan.Width = Width; 6 Rectan.Height = Height; 7 Canvas.SetTop(Rectan,Y); 8 Canvas.SetLeft(Rectan,X); 9 Rectan.Fill = Brushes.Transparent;//サンプルとして透明固定 10 Rectan.Stroke = Brushes.Red;//サンプルとして赤固定 11 Rectan.StrokeThickness = 2;//サンプルとして2固定 12 Rectan.MouseLeftButtonDown += Rect_MouseLeftButtonDown; 13 Rectan.MouseEnter += Rect_MouseEnter; 14 Rectan.MouseLeave += Rect_Leave; 15 Rectan.MouseLeftButtonUp += Rect_MouseLeftButtonUp; 16 Rectan.MouseMove += Rect_MouseMove; 17 MyCanvas.Children.Add(Rectan); 18}

また、以下のようにしたら、正しい位置に表示されるようになった気がします。
正しいかどうかは不明ですが、見た感じ問題ないような気がします。

 X = Canvas.GetLeft(TEST) + TEST.RenderTransform.Value.OffsetX; //OffsetX  Y = Canvas.GetTop(TEST) + TEST.RenderTransform.Value.OffsetY;//OffsetY  Width = X + TEST.RenderSize.Width;//幅  Height = Y + TEST.RenderSize.Height;//高さ

今2点気になっていることがあります。
・Rectangleを消したいが、名前で指定出来ない
「Rectan」を削除し、作成し直すという手を使おうとしてますが
NameでRectangleを検索できずNullになってしまうため、
Rectangleを動かせば動かすほど出来てしまいます。
var NG1=FindName("Rectan");
var NG2 = this.FindName("Rectan") as Rectangle;
Rectangle NG3 = (Rectangle)this.MyCanvas.FindName("Rectan");

・マウス左クリックを外していないのに、勝手にRectangleから外れる
マウスの動きが速かったり、Rectangleが小さいと
クリックしたままでも勝手にドラッグ判定から外れてしまいます。

・そもそも、移動機能は必要なのか…
WPF Canvasにマウスで図形を描画する方法
https://hyperts.net/wpf-drawcanvas-mouse/

Imageの上に、ユーザーがドラッグで四角形を描く。
そして、その四角形の場所、サイズなどを保存したいと思っていました。
描いた四角形の移動や拡縮は、四角形を描いた後の話であり
先に上記サイトのCanvasにRectangleを描く方を実施しようと思います。
そのRectangleを移動および拡縮できるように検討したいと思います。

とりあえず、TN8001様に教えて頂いた「ラバーバンド」というものを
調べてみようと思います。

補足情報(FW/ツールのバージョンなど)

VisualStudio 2019
.NET 4.5(だったはず)
WPF C# (※ WinFormではない)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TN8001

2021/06/21 10:49

こういうことをしている人は結構います。 日本語で検索する場合は、「wpf ラバーバンド」がいいです。 英語で検索する場合は、「wpf resizing adorner」がいいです。 英語で「rubber band」は、範囲選択の四角の話になっていますね。 日本人が勘違いしているのでしょうか?^^;
退会済みユーザー

退会済みユーザー

2021/06/22 01:58

TN8001様 アドバイスありがとうございます! WPF ラバーバンドで調べてみます。良いのが無ければ、英語でも調べます!
TN8001

2021/06/24 12:05

> ・Rectangleを消したいが、名前で指定出来ない Rectanはコードで作ってるのだから、探すまでもなくもう知っているのでは? どうしてもFindNameしたい場合は、RegisterNameしてください。 [FrameworkElement.RegisterName(String, Object) メソッド (System.Windows) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.frameworkelement.registername > ・マウス左クリックを外していないのに、勝手にRectangleから外れる CaptureMouseすると激しく動かしてもウィンドウ外に行っても外れなくなります(はず未確認^^; MouseUpでReleaseMouseCaptureしてください。 [UIElement.CaptureMouse メソッド (System.Windows) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.uielement.capturemouse [UIElement.ReleaseMouseCapture メソッド (System.Windows) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.uielement.releasemousecapture > ・そもそも、移動機能は必要なのか… ドラッグ移動ならMouseDragElementBehaviorがあったりします。 [XamlBehaviorsWpf/MouseDragElementBehavior.cs at master · microsoft/XamlBehaviorsWpf](https://github.com/microsoft/XamlBehaviorsWpf/blob/master/src/Microsoft.Xaml.Behaviors/Layout/MouseDragElementBehavior.cs やりたいことは見えているのですが、どういった方針にするのかがわからないと回答しずらいですね^^;
退会済みユーザー

退会済みユーザー

2021/06/24 23:36

TN8001様 回答ありがとうございます。 画面の端にボタン(移動、拡大縮小など)を用意してカーソルを変更し ボタンに応じて移動などをさせるようにしようと思います。 Canvasにイベントを紐づけ、四角形を描画するところまで進むことが出来ました。 Rectanはコードで作ってるから知っているはずなのですが RemoveでRectanを削除しようにも消せなかったのです。 (今はソースを色々いじったからか、消せるようになりました) >MouseUpでReleaseMouseCaptureしてください。 ありがとうございます。確認します。 再度分からないことがあれば、編集して追記いたします。 よろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問