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

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

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

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

WPF

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

Q&A

解決済

1回答

2667閲覧

マウスドラッグ時の追従でなぜか座標(矩形表示)がずれる

mnhktm

総合スコア25

C#

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

WPF

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

1グッド

0クリップ

投稿2020/01/25 04:52

皆様、お世話になっています。

C# WPF です。 Canvas上の範囲指定でよくあるマウス追従のラバーバンドが表示されるように
したいため、以下のように記述しました。ラバーバンド形状は Rectangle です。

実行すると動くのですが、クリック(マウスダウン)と同時にドラッグすると
最初のDown時のポイント座標(座標表示では正確)とドラッグ時の座標が
マウス先端座標ではなく、マウス先端からさらにX,Yに40~50(変動あり)ほどプラスされた
位置に矩形表示(動きはOK)されてしまいます。
最初のマウスポイント座標は固定、ドラッグ時はマウスに従って変化するのは正常ですが、
座標の取得なのか表示なのか、単に考え方がわるいのか、わかりませんが ラバーバンド矩形
の座標がマウスカーソル先端とはずれる。

よく考えればわかるかもしれませんが、・・・わかりません。
何が間違っているかわかる方、いらっしゃいますでしょうか。

rc は Rectangle
View は Canvas名
vd は 別クラスで座標情報を持たせている
vd.MouseD はマウスダウン時のPoint
vd.MouseM はマウスドラッグ移動時のPoint
Jotai はマウスダウン中の状態

MainWindowのコンストラクタの続きから・・・

    
rc = new Rectangle();
rc.Stroke = new SolidColorBrush(Color.FromRgb(255, 0, 0));
rc.Opacity = 0.5;
rc.StrokeThickness = 3;
rc.Width = 0;
rc.Height = 0;
Canvas.SetTop(rc, 0);
Canvas.SetLeft(rc, 0);
View.Children.Add(rc);
}

/// ----- Mouse Down メソッド ---------- private void Canvas_MouseDown(object sender, MouseButtonEventArgs e) { vd.MouseD = e.GetPosition(this); vd.MouseM = vd.MouseD; Canvas.SetTop(rc, vd.MouseD.X ); Canvas.SetLeft(rc, vd.MouseD.Y); rc.Width = vd.MouseM.X - vd.MouseD.X; rc.Height = vd.MouseM.Y - vd.MouseD.Y; Jotai = MUD.D; // Joutai は Enum型 } /// ----- Mouse Move メソッド -------- private void View_MouseMove(object sender, MouseEventArgs e) { if (Jotai == MUD.D) { vd.MouseM = e.GetPosition(this); rc.Width = vd.MouseM.X - vd.MouseD.X; rc.Height = vd.MouseM.Y - vd.MouseD.Y; } } /// ----- Mouse Up メソッド --------  消すの処理は動きOK完成の後 private void Canvas_MouseUp(object sender, MouseButtonEventArgs e) { if (rc != null) { Jotai = MUD.U; vd.MouseM = e.GetPosition(this); } }
TN8001👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

直接の原因はSetLeftSetTopが逆だからでしょうか(LeftX
e.GetPosition(this)は、e.GetPosition(View)のほうがいいでしょう(レイアウト次第ですが)

あとrc.Widthrc.Heightがマイナスになった(左や上にドラッグした)とき、エラーになりませんか?

cs

1using System.Windows; 2using System.Windows.Controls; 3using System.Windows.Input; 4using System.Windows.Media; 5using System.Windows.Shapes; 6 7namespace Questions237403 8{ 9 public partial class MainWindow : Window 10 { 11 private enum MUD { U, D } 12 private struct VD 13 { 14 public Point MouseD; 15 public Point MouseM; 16 } 17 private Canvas View; 18 private Rectangle rc; 19 private MUD Jotai; 20 private VD vd; 21 22 public MainWindow() 23 { 24 //InitializeComponent(); 25 26 View = new Canvas(); 27 View.Background = Brushes.White; 28 View.MouseDown += Canvas_MouseDown; 29 View.MouseMove += View_MouseMove; 30 View.MouseUp += Canvas_MouseUp; 31 AddChild(View); 32 33 rc = new Rectangle(); 34 rc.Stroke = new SolidColorBrush(Color.FromRgb(255, 0, 0)); 35 rc.Opacity = 0.5; 36 rc.StrokeThickness = 3; 37 rc.Width = 0; 38 rc.Height = 0; 39 View.Children.Add(rc); 40 } 41 42 private void Canvas_MouseDown(object sender, MouseButtonEventArgs e) 43 { 44 vd.MouseD = e.GetPosition(View); 45 vd.MouseM = vd.MouseD; 46 Canvas.SetLeft(rc, vd.MouseD.X); 47 Canvas.SetTop(rc, vd.MouseD.Y); 48 rc.Width = vd.MouseM.X - vd.MouseD.X; 49 rc.Height = vd.MouseM.Y - vd.MouseD.Y; 50 51 Jotai = MUD.D; 52 } 53 54 private void View_MouseMove(object sender, MouseEventArgs e) 55 { 56 if(Jotai == MUD.D) 57 { 58 vd.MouseM = e.GetPosition(View); 59 var w = vd.MouseM.X - vd.MouseD.X; 60 var h = vd.MouseM.Y - vd.MouseD.Y; 61 62 if(0 <= w) 63 { 64 Canvas.SetLeft(rc, vd.MouseD.X); 65 rc.Width = w; 66 } 67 else 68 { 69 Canvas.SetLeft(rc, vd.MouseD.X + w); 70 rc.Width = -w; 71 } 72 73 if(0 <= h) 74 { 75 Canvas.SetTop(rc, vd.MouseD.Y); 76 rc.Height = h; 77 } 78 else 79 { 80 Canvas.SetTop(rc, vd.MouseD.Y + h); 81 rc.Height = -h; 82 } 83 } 84 } 85 86 private void Canvas_MouseUp(object sender, MouseButtonEventArgs e) 87 { 88 Jotai = MUD.U; 89 vd.MouseM = e.GetPosition(View); 90 } 91 } 92}

投稿2020/01/25 08:40

編集2023/07/18 21:43
TN8001

総合スコア9326

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

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

mnhktm

2020/01/25 13:29

TN8001さん、ありがとうございます。 仰る通り SetLeftとSetTop がXY逆でした。がそでれも狂うので、vd.MouseD = e.GetPosition(this); を vd.MouseD = e.GetPosition(View); this → View で正常に動きました。this は必ずしも View ではないのですね。ここを this にするとRectangle のコーナーにマウス先端が合わないようです。 マウスダウン時とドラッグ時の座標が合わないのが判りました。あと、Canvas は途中でXAML側でName="View" としたので、メソッド名を合わせるほうが良いですね。 もっとよく見るように、と言われそうな質問内容でした。 マウス座標のマイナス時の処理もありがとうございます。 助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問