c# 動的に作成したピクチャーボックスをドラッグして移動する

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
もも

c# 動的に作成したピクチャーボックスをドラッグして移動する

#1

投稿記事 by もも » 13年前

フォームのサイズい合わせて動的にピクチャーボックスを作成してそれからマウスでそのピクチャーボックス全体を移動できるようにしたくて
下記のようなプログラムを作ったのですが、なめ方向しか動かなクて困っています。
また移動するときに新たにピクチャーボックスを作っているので効率が悪いような気がしています。
これも解決したいです。

コード:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace map
{
    public partial class Form1 : Form
    {
        //ボタンコントロール配列のフィールドを作成
        private PictureBox[] pictures = new PictureBox[0];
        int Pic_count = 0;
        private bool resize_flag = false;

        public Form1()
        {
            InitializeComponent();

        }

        
        
        private void Form1_Load(object sender, EventArgs e)
        {
            create_picturebox(0,0);
        }

        private void create_picturebox(int custom_x,int custom_y) 
        {

            // フォームのクライアント領域のサイズを取得する
            System.Drawing.Size tSize = this.ClientSize;

            int Height = Size.Height / 255 + 1;
            int Width = Size.Width / 255 + 1;
            
            Pic_count = 0;
            // 取得したフォームのクライアント領域のサイズを表示する
            //MessageBox.Show(tSize.ToString());

            for (int n1 = 1; n1 <= Height; n1++)
            {
                for (int n2 = 1; n2 <= Width; n2++)
                {
                    Pic_count++;
                    Array.Resize(ref this.pictures, Pic_count + 1);
                    this.pictures[Pic_count] = new System.Windows.Forms.PictureBox();
                    this.pictures[Pic_count].Location = new System.Drawing.Point((n2 - 1) * 255 + custom_x, (n1 - 1) * 255 + custom_x);
                    this.pictures[Pic_count].Name = "pictureBox" + Pic_count.ToString();
                    this.pictures[Pic_count].Size = new System.Drawing.Size(255, 255);
                    this.pictures[Pic_count].TabIndex = Pic_count;
                    this.pictures[Pic_count].TabStop = true;
                    this.pictures[Pic_count].BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
                    //↓コレがないとだめ
                    this.pictures[Pic_count].Click += new System.EventHandler(this.pictureBox_Click);
                    this.Controls.Add(this.pictures[Pic_count]);
                    this.pictures[Pic_count].Show();
                    this.pictures[Pic_count].MouseDown += new MouseEventHandler(PictureBox_MouseDown);
                    this.pictures[Pic_count].MouseMove += new MouseEventHandler(PictureBox_MouseMove);

                }

            }
        
        }

        private void remove_picturebox() {
            for (; Pic_count >= 0; Pic_count--)
            {
                this.Controls.Remove(this.pictures[Pic_count]);
            }
        }

        private void pictureBox_Click(object sender, EventArgs e)
        {
            //senderはクリックされたピクチャボックスのどれか
            //PictureBox pict = sender as PictureBox;
            //MessageBox.Show(pict.Name);
        }

        protected override void WndProc(ref System.Windows.Forms.Message m)
        {
            const int WM_EXITSIZEMOVE = 0x0232;
            const int WM_SYSCOMMAND = 0x112;
            const int SC_RESTORE = 0xf120;
            const int SC_MINIMIZE = 0xf020;
            const int SC_MAXIMIZE = 0xf030;

            if (m.Msg == WM_SYSCOMMAND)
            {
                int wparam = m.WParam.ToInt32() & 0xfff0;
                switch (wparam)
                {
                    case SC_MINIMIZE:
                        // 最小化する前
                        base.WndProc(ref m); // ここをコメント化すると最小化されない
                        // 最小化した後
                        return;

                    case SC_MAXIMIZE:
                        // 最大化する前
                        base.WndProc(ref m); // ここをコメント化すると最大化されない
                        // 最大化した後
                        remove_picturebox();
                        create_picturebox(0,0);
                        return;

                    case SC_RESTORE:
                        // 元のサイズに戻す前
                        base.WndProc(ref m); // ここをコメント化すると元のサイズに戻されない
                        // 元のサイズに戻した後
                        remove_picturebox();
                        create_picturebox(0,0);
                        return;

                }
            }

            if (m.Msg == WM_EXITSIZEMOVE && resize_flag)
            {
                //textBox1.Text += "リサイズ完了\r\n";

                remove_picturebox();
                create_picturebox(0,0);

                resize_flag = false;
            }

            base.WndProc(ref m);
        }

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            if (Visible == true) resize_flag = true;
        }

        // マウスポインタの位置を保存する
        private Point mousePoint;

        //マウスのボタンが押されたとき
        private void PictureBox_MouseDown(object sender,System.Windows.Forms.MouseEventArgs e)
        {
            if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
            {
                //位置を記憶する
                mousePoint = new Point(e.X, e.Y);
            }
        }

        //マウスが動いたとき
        private void PictureBox_MouseMove(object sender,System.Windows.Forms.MouseEventArgs e)
        {
            if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
            {
                    remove_picturebox();
                    create_picturebox(e.X - mousePoint.X, e.Y - mousePoint.Y);
            }
        }
          
    }
}


アバター
へにっくす
記事: 634
登録日時: 13年前
住所: 東京都

Re: c# 動的に作成したピクチャーボックスをドラッグして移動する

#2

投稿記事 by へにっくす » 13年前

ツッコミ1:
配列の添え字は0から始まる。
つまり
int array[5];
と宣言したら、array[0]~array[4]が使用できる。
なぜわざわざ1からにするのだ?[0]が無駄だ。
1からにしたいならBasic使いなさい。

ツッコミ2:
ピクチャーボックス全体を移動?
コードみてると全然違う処理のように見えますけど。。
#フォームのサイズを変更すると、256x256固定サイズのピクチャーボックスを並べて埋めるようにしている。移動じゃないよね。。

ツッコミ3:

コード:

private PictureBox[] pictures = new PictureBox[0];
なんですかこれは。こんな初期化はあり得ません。
こうしなさい。

コード:

private PictureBox[] pictures = null;
そして、Width、Heightが決まったら配列のサイズが決まるんだから
いちいちResizeで一つずつ増やすんじゃありません!!

コード:

this.pictures[Width * Height] = new PictureBox[Height * Width];
Pic_count = 0;
for (int n1 = 0; n1 < Height; n1++)
{
	for (int n2 = 0; n2 < Width; n2++, Pic_count++)
	{
		this.pictures[Pic_count] = new PictureBox();
		// 略
		this.Controls.Add(this.pictures[Pic_count]);
	}
}
まあでもこれは好みの問題かなあ・・・
written by へにっくす

もも

Re: c# 動的に作成したピクチャーボックスをドラッグして移動する

#3

投稿記事 by もも » 13年前

地図を動かしているみたいにpictureboxを動かしたいです。

dig
記事: 59
登録日時: 13年前

Re: c# 動的に作成したピクチャーボックスをドラッグして移動する

#4

投稿記事 by dig » 13年前

もも さんが書きました:地図を動かしているみたいにpictureboxを動かしたいです。
何の地図か書くと解答が得られるかもしれません。
もも さんが書きました:フォームのサイズい合わせて動的にピクチャーボックスを作成してそれからマウスでそのピクチャーボックス全体を移動できるようにしたくて
下記のようなプログラムを作ったのですが、なめ方向しか動かなクて困っています。
また移動するときに新たにピクチャーボックスを作っているので効率が悪いような気がしています。
これも解決したいです。
プログラムが何をしたいのかさっぱりわかりません。
すでに配置されているピクチャーボックスを動かすのでしょうか?であれば既に配置済みのピクチャーボックスのLocationプロパティを変更し、Refresh()すればいいだけかと。
WndProcオーバライドも必要ないような気がします。

アバター
沖 滉均
記事: 237
登録日時: 14年前
住所: K県F市

Re: c# 動的に作成したピクチャーボックスをドラッグして移動する

#5

投稿記事 by 沖 滉均 » 13年前

もも さんが書きました:地図を動かしているみたいにpictureboxを動かしたいです。
地図を動かしているみたいにというのはgoogleマップのように画像の一分を表示してマウスでスクロールして部分を表示したい…
というようなイメージでしょうか?
だとしたら、何枚ものピクチャーボックスを作成する必要はあるのでしょうか?
There is no royal road to learning.
codeタグで指定できる言語
画像

もも

Re: c# 動的に作成したピクチャーボックスをドラッグして移動する

#6

投稿記事 by もも » 13年前

>すでに配置されているピクチャーボックスを動かすのでしょうか?であれば既に配置済みのピクチャーボックスのLocationプロパティを変更し、Refresh()すればいいだけかと。

これはできるのですが移動がおかしいのです。
マウスで移動しようとしても斜め方向しか動かないのです。

アバター
へにっくす
記事: 634
登録日時: 13年前
住所: 東京都

Re: c# 動的に作成したピクチャーボックスをドラッグして移動する

#7

投稿記事 by へにっくす » 13年前

もも さんが書きました:>すでに配置されているピクチャーボックスを動かすのでしょうか?であれば既に配置済みのピクチャーボックスのLocationプロパティを変更し、Refresh()すればいいだけかと。

これはできるのですが移動がおかしいのです。
マウスで移動しようとしても斜め方向しか動かないのです。
確かにLocationプロパティをいじっているようですが、、あっ!!
よーく目を凝らして見てみようか…縦方向に何を入れてるんだ?

コード:

this.pictures[Pic_count].Location = new System.Drawing.Point((n2 - 1) * 255 + custom_x, (n1 - 1) * 255 + custom_x);
またpictureboxをいちいち追加/削除しているのはよくないです。
オーバーライドしてるWndProcもなくした方がいいと思います。
written by へにっくす

dig
記事: 59
登録日時: 13年前

Re: c# 動的に作成したピクチャーボックスをドラッグして移動する

#8

投稿記事 by dig » 13年前

もも さんが書きました:>すでに配置されているピクチャーボックスを動かすのでしょうか?であれば既に配置済みのピクチャーボックスのLocationプロパティを変更し、Refresh()すればいいだけかと。

これはできるのですが移動がおかしいのです。
マウスで移動しようとしても斜め方向しか動かないのです。
へにっくすさんや沖さんの返信にも答えたほうがよいかと...
両者の返信も的外れのようには思えません。

とりあえず配置済みのピクチャーボックスを動かすサンプルを書いておきます。以下で試してみてはどうでしょうか?
※フォームにピクチャーボックスを一つ配置し、そのピクチャーボックスのMouseMoveイベントをpictureBox1_MouseMoveという名前でセットし、下記のコードをコピペすると動くかと思います。

コード:

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
            {
                    pictureBox1.Location = new Point(pictureBox1.Location.X + e.X, pictureBox1.Location.Y + e.Y);
                    pictureBox1.Refresh();
            }
        }
    }
}
それとおせっかいかもしれませんが、コントロールの位置はあまり変更しないほうがよいかと思います。
ユーザーにとってピクチャーボックス自体が動くことにあまりメリットはないように思います。
むしろコントロール自体が動くことは混乱の元になるような気がします。(例外はあるかと思いますが)

以上参考までに

もも

Re: c# 動的に作成したピクチャーボックスをドラッグして移動する

#9

投稿記事 by もも » 13年前

>コントロール自体が動くことは混乱の元になるような気がします。
他にはどのような方法があるのでしょうか?

アバター
バグ
記事: 130
登録日時: 14年前
住所: 愛媛県
連絡を取る:

Re: c# 動的に作成したピクチャーボックスをドラッグして移動する

#10

投稿記事 by バグ » 13年前

>>他にはどのような方法があるのでしょうか?

PictureBoxそのものではなく、表示してある画像の表示位置を動かすのでは駄目なのですか?

もも

Re: c# 動的に作成したピクチャーボックスをドラッグして移動する

#11

投稿記事 by もも » 13年前

それば出来ないのです。

一応ここまで出来ました。
ウインドウのサイズに合わせて動的に一定のサイズのピクチャーボックスを配置して一つ一つをどレッグ出来るようにしました。
次にやることは
すべてのピクチャーボックスを一緒に移動したいのですがどうすればいいでしょうか?

コード:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        // プライベートなフィールドとして配列を定義する
        private PictureBox[] myPictureBoxes;
        // マウスポインタの位置を保存する
        private Point mousePoint;
        int Pic_count = 0;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Create_PictureBox();
        }

        private void Create_PictureBox()
        {
            // フォームのクライアント領域のサイズを取得する
            System.Drawing.Size tSize = this.ClientSize;

            int Height = Size.Height / 255 + 1;
            int Width = Size.Width / 255 + 1;
            Pic_count = 0;

            // 10 個の配列を確保する
            this.myPictureBoxes = new PictureBox[500];

            for (int n1 = 0; n1 < Height; n1++)
            {
                for (int n2 = 0; n2 < Width; n2++)
                {
                    // 新しいインスタンスを生成する
                    this.myPictureBoxes[Pic_count] = new PictureBox();

                    // ここで、プロパティなどを必要に応じて設定します
                    this.myPictureBoxes[Pic_count].Name = "PictureBox" + Pic_count.ToString();
                    this.myPictureBoxes[Pic_count].Size = new System.Drawing.Size(255, 255);
                    this.myPictureBoxes[Pic_count].Location = new System.Drawing.Point(n2 * 255 , n1 * 255);
                    this.myPictureBoxes[Pic_count].BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;

                    // このコントロールをフォームに追加する
                    this.Controls.Add(this.myPictureBoxes[Pic_count]);

                    // イベントも統合する場合は、イベント ハンドラを追加する
                    new ControlDragable(myPictureBoxes[Pic_count]); 
                    
                    Pic_count++;
                }
            }
        }      
    }
    
    public class ControlDragable
        {
            private bool isDragging = false;
            private Point point = new Point();
            public ControlDragable(Control ctr)
            {
                ctr.MouseDown += (s, mouseDownArg) =>
                {
                    isDragging = true;
                    point.X = mouseDownArg.X;
                    point.Y = mouseDownArg.Y;
                };
                ctr.MouseMove += (s, mouseMoveArg) =>
                {
                    if (!isDragging) { return; }
                    ctr.Left += mouseMoveArg.X - point.X;
                    ctr.Top += mouseMoveArg.Y - point.Y;
                };
                ctr.MouseUp += (s, mouseUpArg) =>
                {
                    isDragging = false;
                };
            }
        }
}


dig
記事: 59
登録日時: 13年前

Re: c# 動的に作成したピクチャーボックスをドラッグして移動する

#12

投稿記事 by dig » 13年前

もも さんが書きました:それば出来ないのです。

一応ここまで出来ました。
ウインドウのサイズに合わせて動的に一定のサイズのピクチャーボックスを配置して一つ一つをどレッグ出来るようにしました。
次にやることは
すべてのピクチャーボックスを一緒に移動したいのですがどうすればいいでしょうか?
出来ないって...そんなことあるんですか?
やっぱりどんな地図アプリを参考にしているかまず示すべきですよ。グーグルマップだとか何か参考にしてるものがあるのでしょう?
コントロールそのものを動かす地図ってなんかイメージがまったく湧きません。

とりあえず、とにもかくにも何が何でもピクチャーボックスを動かしたいようなんで
ピクチャーボックスをプログラム中で確保・配置し、そのピクチャーボックスを全てイベント補足しマウスで移動するサンプルを以下に貼っておきます。

※新規のまっさらなフォームに以下のコードをコピペすれば動くかと思います。

コード:

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        //ピクチャーボックス格納配列
        PictureBox[] pictureBoxArray;

        public Form1()
        {
            InitializeComponent();

            //ピクチャーボックスの作成、追加-------
            pictureBoxArray = new PictureBox[9];

            int picture_box_index = 0;
            Random random = new Random();

            for (int x = 0; x < 153; x += 51)
            {
                for (int y = 0; y < 153; y += 51)
                {
                    pictureBoxArray[picture_box_index] = new PictureBox();
                    pictureBoxArray[picture_box_index].Size = new Size(50, 50);
                    pictureBoxArray[picture_box_index].Location = new Point(x, y);
                    pictureBoxArray[picture_box_index].BackColor = Color.FromArgb(random.Next(0, 255), random.Next(0, 255), random.Next(0, 255));
                    pictureBoxArray[picture_box_index].MouseMove += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseMove);

                    this.Controls.Add(pictureBoxArray[picture_box_index]);
                    picture_box_index++;
                }
            }
            //-----------------------------------------
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
            {
                //各ピクチャーボックス別々に動かすなら以下------------------------------------------------------
                //PictureBox picture_box = (PictureBox)sender;
                //picture_box.Location = new Point(picture_box.Location.X + e.X, picture_box.Location.Y + e.Y);
                //-------------------------------------------------------------------------------------------------

                //全てのピクチャーボックスを同時に動かすなら以下-----------------------------------------------
                for (int i = 0; i < pictureBoxArray.Length; i++)
                {
                    pictureBoxArray[i].Location = new Point(pictureBoxArray[i].Location.X + e.X, pictureBoxArray[i].Location.Y + e.Y);
                }
                //-------------------------------------------------------------------------------------------------
            }
        }
    }
}
以上、参考まで。

閉鎖

“C言語何でも質問掲示板” へ戻る