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

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

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

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

Q&A

解決済

1回答

3938閲覧

Graphicsクラスを使ってpictureBoxを再描画したい

joihhooijohog

総合スコア15

C#

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

0グッド

0クリップ

投稿2019/03/08 09:28

編集2019/03/08 09:31

現在、なぜか初心者なのに自分の実力を試したい!!と簡単なSLG(シミュレーションゲーム)を
作っていてがっつり壁にぶち当たってます。
どこかといいますと、クリック時に移動範囲を求めて、マップを表示している
pictureboxをGraphicsを利用して再描画する部分です。
以下のコードを実行しても、更新されません。

public class Char//キャラクターの基本クラス {     ~~~~~     中略 ~~~~~ protected void CharPic(PictureBox pic) { pic.Click += new EventHandler(PicClick); } void PicClick(object sender, EventArgs e)//キャラクタークリック時に移動処理等をする { MapDate[Y, X] = move; Search(Y, X, move);//移動範囲求める関数 Search_of_Move(MapDate);//↑で求めたところに画像を表示する関数 } void Search(int y,int x,int e)//↑→←↓ { MapDate[y, x] = e; if (e == 0) { return; } if (MapDate[y - 1, x] < e) Search(y - 1, x, e - 1); if (MapDate[y, x + 1] < e) Search(y, x + 1, e - 1); if (MapDate[y, x - 1] < e) Search(y, x - 1, e - 1); if (MapDate[y + 1, x] < e) Search(y + 1, x, e - 1); } void Search_of_Move(int[,] map) { int x = 0; int y = 0; int Xs = MapDate.GetLength(1); int Ys = MapDate.GetLength(0); foreach (int m in map)//移動範囲はどこか、ちまちま探していく { if (x != Xs || y != Ys) { if (map[y, x] > 0) { Move move = new Move(x,y);//描画処理 } } if (x != Xs - 1) { x++; } else if (y != Ys - 1) { x = 0; y++; } } } ~~~~~       中略      ~~~~~ } }
public class Move//描画処理 { public PictureBox pic; private MapManager map = new MapManager(); private Form1 Form1=new Form1(); public Move(int X,int Y) { Bitmap canvas = map.absolute_map;//ここでマップデータを取得 Graphics g = Graphics.FromImage(canvas); Image img = Image.FromFile(@"C:\Users\owner\Documents\課題用\DateImage\move.png"); g.DrawImage(img, X*42, Y*42, img.Width, img.Height); img.Dispose(); g.Dispose(); Form1.Move_click(canvas); } }}
public partial class Form1 : Form { private MapManager map = new MapManager(); private CharDate CharDate; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { pictureBoxMap.Image = map.absolute_map; } private void Timer1_Tick(object sender, EventArgs e) { pictureBoxMap.Refresh(); } ~~~~~     中略     ~~~~~ public void Move_click(Bitmap can) { pictureBoxMap.Image = can; //クラスmoveで描画したやつ } }

イメージ説明
####実行時(なにも表示されず)
イメージ説明
###理想。黄色のところに画像を挿入し、再描画したいです。
直接関わりのなさそうなとこは略しました。
必要あれば指摘お願いします。
スーパースパゲッティコードですみません。

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

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

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

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

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

guest

回答1

0

ベストアンサー

ソースの全貌がわからないので、何点か思ったことを書きます
・OnPaintの引数にある、 PaintEventArgs eの
e.Graphics を描画対象とするべきじゃないでしょうか
現在は、Graphics g = Graphics.FromImage(canvas); となっていて、
描画対象がMapManager の中にある謎の領域に描画しています

・毎回、ファイルから画像を読み取り、disposeするのはパフォーマンス的に良くないので、
何処かで読み込んだら、そのまま保持するべきだと思います

・Invalidate() はどこかに入れていますか?

投稿2019/03/08 10:41

izmktr

総合スコア2856

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

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

joihhooijohog

2019/03/08 12:37

public class Move { private MapManager map = new MapManager(); private Form1 Form1=new Form1(); private Bitmap canvas; private Graphics g; private Image img; private int x, y; public Move(int X, int Y) { canvas = map.absolute_map;//ここでマップデータを取得 Graphics g = Graphics.FromImage(canvas); Image img = Image.FromFile(@"C:\Users\owner\Documents\課題用\DateImage\move.png"); x = X; y = Y; } public void Panel1_Paint(object sender, PaintEventArgs e) { e.Graphics.DrawImage(img, x * 42, y * 42, img.Width, img.Height); img.Dispose(); g.Dispose(); Form1.Move_click(canvas); } } } に変更したら、form1のコンストラクターだけしか読み込まれなくなりました。 どうすればいいでしょうか
joihhooijohog

2019/03/08 13:40

すみません、自己解決出来ました。 本題はなんとかできそうですが、何処かで読み込んだら、そのまま保持は、コンストラクターでImage型で定義しておくということですか?
izmktr

2019/03/08 14:35

そうです メンバー変数にImage型をおいて、プログラムが終わるまで保持するのが一般的です
joihhooijohog

2019/03/09 14:50

public Move(int X, int Y) { pic.Image = map.absolute_map;//ここでマップデータを取得 pic.Paint +=new PaintEventHandler(paint); img = Image.FromFile(@"C:\Users\owner\Documents\課題用\DateImage\move.png"); x = X; y = Y; Form1.Controls.Add(pic); } private void paint(object sender, System.Windows.Forms.PaintEventArgs e) { Graphics g = e.Graphics; g = Graphics.FromImage(img); g.DrawImage(img, x * 42, y * 42, img.Width, img.Height); pic.Dispose(); g.Dispose(); Form1.Move_click(pic); } に変更しましたが、paintを実行させるにはどうすればいいですか?
izmktr

2019/03/10 05:33

そもそもその書き方が違うんですよね… onpaintに該当するものはプロパティから入れます C#のプログラムはきっちり出来ている感じがしますが、 WindowsFormに関するプログラムの基礎が出来てないようなので、入門書を一冊終わらせたほうがいいと思います
joihhooijohog

2019/03/10 13:33

Onpaint関連を利用せず、再描画は可能ですか?
joihhooijohog

2019/03/10 13:58

一応、public Move(int X, int Y) { Bitmap canvas = new Bitmap(Form1.Picture.Image); Graphics g = Graphics.FromImage(canvas); Image img = Image.FromFile(@"C:\Users\owner\Documents\課題用\DateImage\tile2.bmp"); Rectangle Rect = new Rectangle(X * 42, Y * 42,42,42); g.DrawImage(img,X*42,Y*42,Rect,GraphicsUnit.Pixel); img.Dispose(); g.Dispose(); Form1.Picture.Image = canvas; Form1.Refresh_Pic(); } にして、From1のRefresh.Pic関数でPicture.Invalidate();しているのですが...
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問