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

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

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

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

Q&A

解決済

1回答

10208閲覧

コントロールの縦横比を固定して拡大・縮小する

k1500

総合スコア12

C#

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

0グッド

0クリップ

投稿2018/06/18 10:39

下記サイト様のコードを参考にpictureBoxをD&Dで縦横比を固定したまま拡大・縮小できるクラスを考えておりますが、うまくいきません。
(https://anis774.net/codevault/danddsizechanger.html)

縦の変化量を常に横の4/3倍としているように書き換えたのですが希望する動きになっていない状態です。

問題点をご指摘頂けると助かります。
宜しくお願いします。

C#

1uclass DAndDSizeChanger 2 { 3 Control mouseListner; 4 Control sizeChangeCtrl; 5 DAndDArea sizeChangeArea; 6 Size lastMouseDownSize; 7 Point lastMouseDownPoint; 8 DAndDArea status; 9 int sizeChangeAreaWidth; 10 Cursor defaultCursor; 11 12 const double fixedRate = (double)4 / 3; 13 14 /// <param name="mouseListner">マウス入力を受け取るコントロール</param> 15 /// <param name="sizeChangeCtrl">マウス入力によってサイズが変更されるコントロール</param> 16 /// <param name="sizeChangeArea">上下左右のサイズ変更が有効になる範囲を指定</param> 17 /// <param name="sizeChangeAreaWidth">サイズ変更が有効になる範囲の幅を指定</param> 18 public DAndDSizeChanger(Control mouseListner, Control sizeChangeCtrl, DAndDArea sizeChangeArea, int sizeChangeAreaWidth) 19 { 20 this.mouseListner = mouseListner; 21 this.sizeChangeCtrl = sizeChangeCtrl; 22 this.sizeChangeAreaWidth = sizeChangeAreaWidth; 23 this.sizeChangeArea = sizeChangeArea; 24 defaultCursor = mouseListner.Cursor; 25 26 mouseListner.MouseDown += new MouseEventHandler(mouseListner_MouseDown); 27 mouseListner.MouseMove += new MouseEventHandler(mouseListner_MouseMove); 28 mouseListner.MouseUp += new MouseEventHandler(mouseListner_MouseUp); 29 } 30 31 void mouseListner_MouseDown(object sender, MouseEventArgs e) 32 { 33 lastMouseDownPoint = e.Location; 34 lastMouseDownSize = sizeChangeCtrl.Size; 35 36 //動作を決定 37 status = DAndDArea.None; 38 if (getTop().Contains(e.Location)) 39 { 40 status |= DAndDArea.Top; 41 } 42 if (getLeft().Contains(e.Location)) 43 { 44 status |= DAndDArea.Left; 45 } 46 if (getBottom().Contains(e.Location)) 47 { 48 status |= DAndDArea.Bottom; 49 } 50 if (getRight().Contains(e.Location)) 51 { 52 status |= DAndDArea.Right; 53 } 54 55 if (status != DAndDArea.None) 56 { 57 mouseListner.Capture = true; 58 } 59 } 60 61 void mouseListner_MouseMove(object sender, MouseEventArgs e) 62 { 63 //カーソルを変更 64 if ((getTop().Contains(e.Location) && 65 getLeft().Contains(e.Location)) || 66 (getBottom().Contains(e.Location) && 67 getRight().Contains(e.Location))) 68 { 69 70 mouseListner.Cursor = Cursors.SizeNWSE; 71 } 72 else if ((getTop().Contains(e.Location) && 73 getRight().Contains(e.Location)) || 74 (getBottom().Contains(e.Location) && 75 getLeft().Contains(e.Location))) 76 { 77 mouseListner.Cursor = Cursors.SizeNESW; 78 } 79 80 else 81 { 82 mouseListner.Cursor = defaultCursor; 83 } 84 85 86 87 if (e.Button == MouseButtons.Left) 88 { 89 int diffX = e.X - lastMouseDownPoint.X; 90 int diffY = e.Y - lastMouseDownPoint.Y; 91 92 93 94 if ((status & DAndDArea.Left) == DAndDArea.Left && (status & DAndDArea.Top) == DAndDArea.Top)//左上 95 { 96 97 98 int w = sizeChangeCtrl.Width; 99 sizeChangeCtrl.Width -= diffX; 100 sizeChangeCtrl.Left += w - sizeChangeCtrl.Width; 101 102 int h = sizeChangeCtrl.Height; 103 sizeChangeCtrl.Height -= diffY; 104 //sizeChangeCtrl.Top += (int)(fixedRate * (h - sizeChangeCtrl.Height) + 0.5); 105 sizeChangeCtrl.Top += h - sizeChangeCtrl.Height; 106 } 107 if ((status & DAndDArea.Right) == DAndDArea.Right && (status & DAndDArea.Top) == DAndDArea.Top)//右上サイド 108 { 109 110 111 sizeChangeCtrl.Width = lastMouseDownSize.Width + diffX; 112 113 int h = sizeChangeCtrl.Height; 114 sizeChangeCtrl.Height -= diffY; 115 //sizeChangeCtrl.Top += (int)(fixedRate * (h - sizeChangeCtrl.Height) + 0.5); 116 sizeChangeCtrl.Top += h - sizeChangeCtrl.Height; 117 } 118 119 120 if ((status & DAndDArea.Left) == DAndDArea.Left && (status & DAndDArea.Bottom) == DAndDArea.Bottom)//左下 121 { 122 123 int w = sizeChangeCtrl.Width; 124 sizeChangeCtrl.Width -= diffX; 125 sizeChangeCtrl.Left += w - sizeChangeCtrl.Width; 126 127 //sizeChangeCtrl.Height = (int)(fixedRate * (lastMouseDownSize.Height + diffY) + 0.5); 128 sizeChangeCtrl.Height = lastMouseDownSize.Height + diffY; 129 } 130 if ((status & DAndDArea.Right) == DAndDArea.Right && (status & DAndDArea.Bottom) == DAndDArea.Bottom) //右下 131 { 132 133 134 sizeChangeCtrl.Width = lastMouseDownSize.Width + diffX; 135 //sizeChangeCtrl.Height = (int)(fixedRate * (lastMouseDownSize.Height + diffY) + 0.5); 136 sizeChangeCtrl.Height = lastMouseDownSize.Height + diffY; 137 } 138 139 140 } 141 } 142 143 void mouseListner_MouseUp(object sender, MouseEventArgs e) 144 { 145 mouseListner.Capture = false; 146 } 147 148 /// <summary> 149 /// ポイントがD&Dするとサイズが変更されるエリア内にあるかどうかを判定します。 150 /// </summary> 151 public bool ContainsSizeChangeArea(Point p) 152 { 153 return getTop().Contains(p) || 154 getBottom().Contains(p) || 155 getLeft().Contains(p) || 156 getRight().Contains(p); 157 } 158 159 private Rectangle getTop() 160 { 161 if ((sizeChangeArea & DAndDArea.Top) == DAndDArea.Top) 162 { 163 return new Rectangle(0, 0, mouseListner.Width, sizeChangeAreaWidth); 164 } 165 else 166 { 167 return new Rectangle(); 168 } 169 } 170 171 private Rectangle getBottom() 172 { 173 if ((sizeChangeArea & DAndDArea.Bottom) == DAndDArea.Bottom) 174 { 175 return new Rectangle(0, mouseListner.Height - sizeChangeAreaWidth, 176 mouseListner.Width, sizeChangeAreaWidth); 177 } 178 else 179 { 180 return new Rectangle(); 181 } 182 } 183 184 private Rectangle getLeft() 185 { 186 if ((sizeChangeArea & DAndDArea.Left) == DAndDArea.Left) 187 { 188 return new Rectangle(0, 0, 189 sizeChangeAreaWidth, mouseListner.Height); 190 } 191 else 192 { 193 return new Rectangle(); 194 } 195 } 196 197 private Rectangle getRight() 198 { 199 if ((sizeChangeArea & DAndDArea.Right) == DAndDArea.Right) 200 { 201 return new Rectangle(mouseListner.Width - sizeChangeAreaWidth, 0, 202 sizeChangeAreaWidth, mouseListner.Height); 203 } 204 else 205 { 206 return new Rectangle(); 207 } 208 } 209 } 210 211 public enum DAndDArea 212 { 213 None = 0, 214 Top = 1, 215 Bottom = 2, 216 Left = 4, 217 Right = 8, 218 All = 15 219 220 } 221}

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

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

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

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

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

g_uo

2018/06/19 01:47

[お願い] 質問の際クラス内部だけでなく、このクラスを呼び出しているコードも記載してくださいますようお願いします。回答者が動作を確認する際に役立つうえ、より多くの回答を得ることができると思います。
k1500

2018/06/19 01:49

わかりました。
guest

回答1

0

ベストアンサー

こんにちは。

ドラッグ後のコントロールの幅または高さをもとに、他方の長さを計算すれば比率は維持されます。
次のソースでは、ドラッグ後の幅(sizeChangeCtrl.Width)に対して高さ、およびTopを計算して反映させています。

修正対象個所はvoid mouseListner_MouseMove(object sender, MouseEventArgs e)だけですので、抜粋しています。

csharp

1 void mouseListner_MouseMove(object sender, MouseEventArgs e) 2 { 3 //カーソルを変更 4 if ((getTop().Contains(e.Location) && 5 getLeft().Contains(e.Location)) || 6 (getBottom().Contains(e.Location) && 7 getRight().Contains(e.Location))) 8 { 9 10 mouseListner.Cursor = Cursors.SizeNWSE; 11 } 12 else if ((getTop().Contains(e.Location) && 13 getRight().Contains(e.Location)) || 14 (getBottom().Contains(e.Location) && 15 getLeft().Contains(e.Location))) 16 { 17 mouseListner.Cursor = Cursors.SizeNESW; 18 } 19 20 else 21 { 22 mouseListner.Cursor = defaultCursor; 23 } 24 25 if (e.Button == MouseButtons.Left) 26 { 27 int diffX = e.X - lastMouseDownPoint.X; 28 int diffY = e.Y - lastMouseDownPoint.Y; 29 30 if ((status & DAndDArea.Left) == DAndDArea.Left && (status & DAndDArea.Top) == DAndDArea.Top)//左上 31 { 32 33 int w = sizeChangeCtrl.Width; 34 sizeChangeCtrl.Width -= diffX; 35 sizeChangeCtrl.Left += w - sizeChangeCtrl.Width; 36 37 int h = sizeChangeCtrl.Height; 38 int h2 = sizeChangeCtrl.Width * 3 / 4; 39 sizeChangeCtrl.Height = h2; 40 sizeChangeCtrl.Top += h - h2; 41 } 42 if ((status & DAndDArea.Right) == DAndDArea.Right && (status & DAndDArea.Top) == DAndDArea.Top)//右上サイド 43 { 44 45 sizeChangeCtrl.Width = lastMouseDownSize.Width + diffX; 46 47 int h = sizeChangeCtrl.Height; 48 int h2 = sizeChangeCtrl.Width * 3 / 4; 49 sizeChangeCtrl.Height = h2; 50 sizeChangeCtrl.Top += h - h2; 51 } 52 53 if ((status & DAndDArea.Left) == DAndDArea.Left && (status & DAndDArea.Bottom) == DAndDArea.Bottom)//左下 54 { 55 56 int w = sizeChangeCtrl.Width; 57 sizeChangeCtrl.Width -= diffX; 58 sizeChangeCtrl.Left += w - sizeChangeCtrl.Width; 59 sizeChangeCtrl.Height = sizeChangeCtrl.Width * 3 / 4; 60 } 61 if ((status & DAndDArea.Right) == DAndDArea.Right && (status & DAndDArea.Bottom) == DAndDArea.Bottom) //右下 62 { 63 64 sizeChangeCtrl.Width = lastMouseDownSize.Width + diffX; 65 sizeChangeCtrl.Height = sizeChangeCtrl.Width * 3 / 4; 66 } 67 68 } 69 }

補足

  • 今回の修正は縦横比が4:3固定になっています
  • 参考リンクのソースを基にしているため、TextBoxでテストしています
  • コントロール端をつかんだ瞬間コントロールサイズが変更されます(もともとの動きがそうなってる?)

ご参考になれば幸いでございます。

投稿2018/06/19 01:46

g_uo

総合スコア212

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

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

k1500

2018/06/19 01:49

ありがとうございます。 おかげさまでうまくいきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問