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

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

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

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

Q&A

3回答

6556閲覧

C#で横スクロールバーをスクロールした時にGraphicsの描画が更新されるようにしたい

kemomimi_sabal

総合スコア12

C#

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

0グッド

1クリップ

投稿2019/05/27 02:42

編集2019/05/27 17:25

こんにちは。

パネルをスクロールした時に描画の続きの部分が描画されるようにしたいのですが、現状では続きの部分が描画されず、途切れてしまいます

Panelの上にPictureBoxを置いてスクロールバーを表示させることには成功しましたが、やはりスクロールした時に途切れ、再描画がされません。

下記がコードです

C#

1 private void KeyBoard_Paint(object sender, PaintEventArgs e) 2 { 3 int octave_draw_size_y = PianoRoll.white_key_board_height_list.Sum(); 4 int measure_off_no, measure_count = 1; 5 int new_measure_count = 1; 6 int offset, measure_x_draw; 7 measure_x_draw = measure_count * PianoRoll.MEASURE_WIDTH; 8 measure_off_no = 0; 9 offset = measure_off_no * PianoRoll.MEASURE_WIDTH; 10 new_measure_count += measure_count; 11 // 白鍵と黒鍵の描画 12 SolidBrush white_keyboard_color = new SolidBrush(Color.FromArgb(255, 255, 255)); 13 Pen black_line_color = new Pen(Color.FromArgb(0, 0, 0), 1); 14 black_line_color.Alignment = System.Drawing.Drawing2D.PenAlignment.Inset; 15 SolidBrush black_keyboard_color = new SolidBrush(Color.FromArgb(10, 10, 10)); 16 // 白鍵の描画 17 int white_start_y = 0; 18 for (int i = 0; i < PianoRoll.octave_num; i++) 19 { 20 foreach (int height in PianoRoll.white_key_board_height_list) 21 { 22 e.Graphics.FillRectangle(white_keyboard_color, 0, white_start_y, PianoRoll.WHITE_KEYBOARD_WIDTH, height); 23 e.Graphics.DrawRectangle(black_line_color, 0, white_start_y, PianoRoll.WHITE_KEYBOARD_WIDTH, height); 24 white_start_y += height; 25 } 26 } 27 // 黒鍵の描画 28 for (int i = 0; i < PianoRoll.octave_num; i++) 29 { 30 foreach (int black_key_board_start_y in PianoRoll.black_key_board_start_y_list) 31 { 32 e.Graphics.FillRectangle(black_keyboard_color, 0, black_key_board_start_y + (octave_draw_size_y * i), PianoRoll.BLACK_KEYBOARD_WIDTH, PianoRoll.BLACK_KEYBOARD_HEIGHT); 33 } 34 35 } 36 }

4時間ほど悩みましたが解決に至りません。どうしたらいいのでしょうか
スクロールした時に再描画して一番下まで見れるようにしたい。横は時間が追加されてある数を超えたら再描画

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

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

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

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

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

Zuishin

2019/05/27 02:48

PictureBox ではいけないんですか?
Zuishin

2019/05/27 03:14

それはどういう利点がありますか?
kemomimi_sabal

2019/05/27 03:18

歌声合成ソフトの開発をしているのですが、それにあたり音符などの更新を容易にするためです
Zuishin

2019/05/27 03:22

それに Panel を使う利点の話です。
kemomimi_sabal

2019/05/27 03:29

panelの上にpictureboxを置いてpanelのAutoScrollをtrueにしましたが期待した動作を得られなかったのでpanelの上に直接描画してhscrollとvscrollを個別に配置しています
Zuishin

2019/05/27 03:30

特に利点が無いのであれば、スクロールされるたびに Invalidate を行うのではなく、パネルの上に PictureBox を置き、PictureBox を適当な大きさに変更してスクロールはその下のパネルに任せるのが一番楽ではないかと思います。 私であれば PictureBox の代わりに CustomControl を使いますが、当面どちらでも問題ないかと。
Zuishin

2019/05/27 03:33

「期待した動作」が何かにもよりますが、どのみちそこを伏せていたのでは適切な回答はつきにくいので、「やってみたこと」としてその方法を書き、また期待する動作と実際の動作を書くのがいいのではないでしょうか。
kemomimi_sabal

2019/05/27 03:50

パネルをスクロールした時に描画の続きの部分が描画されるようにしたいのです
kemomimi_sabal

2019/05/27 03:51

ですが、現状では続きの部分が描画されず、途切れてしまいます
Zuishin

2019/05/27 04:10

その方法で続きが途切れるのは多分画像に描いていないからです。なんとなくやりたいことはわかりました。
kemomimi_sabal

2019/05/27 04:50

Panelの上にPictureBoxを置いてスクロールバーを表示させることには成功しましたが、やはり描画がされません。 下記がコードです private void NoteEdit_Scroll(object sender, ScrollEventArgs e) { pictureBox1.Update(); }
YAmaGNZ

2019/05/27 22:12

提示ソースは左側のキーボード部分の描画だと思いますが、これが右側のスクロールさせたい部分とどう関係があるのですか?
Zuishin

2019/05/27 23:49

下記がコードですって言われても。私や YAmaGNZ さんのコードは動きましたか? 動いたならそれを応用すればいいのではないですか? もともとのコードがほぼ隠されている状態で、意図を丁寧に確認して十分なコードを出したつもりですが。
guest

回答3

0

Zuishinさんの言っていることはこういうことかと

C#

1public partial class Form1 : Form 2{ 3 private Panel pnlScore, pnlKey; 4 private PictureBox picScore, picKeybord; 5 6 public Form1() 7 { 8 InitializeComponent(); 9 10 //フォームの大きさ 11 this.Size = new Size(800, 500); 12 13 //表示領域のパネル 14 this.pnlScore = new Panel() { Location = new Point(130, 10), Size = new Size(640, 370), AutoScroll = true }; 15 this.pnlKey = new Panel() { Location = new Point(10, 10), Size = new Size(120, 350) }; 16 this.Controls.Add(pnlKey); 17 this.Controls.Add(pnlScore); 18 19 //描画するPictureBox 20 this.picKeybord = new PictureBox() { Location = new Point(0, 0), Size = new Size(120, 600) }; 21 this.picScore = new PictureBox() { Location = new Point(0, 0), Size = new Size(5000, 600) }; 22 pnlKey.Controls.Add(picKeybord); 23 pnlScore.Controls.Add(picScore); 24 25 this.picKeybord.Paint += new System.Windows.Forms.PaintEventHandler(this.picKeybord_Paint); 26 this.picScore.Paint += new System.Windows.Forms.PaintEventHandler(this.picScore_Paint); 27 this.pnlScore.Scroll += new System.Windows.Forms.ScrollEventHandler(this.pnlFumen_Scroll); 28 29 } 30 31 private void pnlFumen_Scroll(object sender, ScrollEventArgs e) 32 { 33 //譜面部分の縦スクロールにキーボード部分を連動させる 34 if (e.ScrollOrientation == ScrollOrientation.VerticalScroll) 35 { 36 picKeybord.Top = -e.NewValue; 37 } 38 } 39 40 private void picKeybord_Paint(object sender, PaintEventArgs e) 41 { 42 for (int y = 0; y < picKeybord.Height; y += 50) 43 { 44 e.Graphics.FillRectangle(Brushes.Black, 0, y, picKeybord.Width, 30); 45 } 46 } 47 48 private void picScore_Paint(object sender, PaintEventArgs e) 49 { 50 for (int x = 0; x < picScore.Width; x += 50) 51 { 52 for (int y = 0; y < picScore.Height; y += 50) 53 { 54 if(x % 100 != 0 && y % 100 == 0) 55 { 56 e.Graphics.FillRectangle(Brushes.Black, x, y, 50, 50); 57 } 58 } 59 } 60 } 61 62}

PictureBoxをしっかり描画してやれば、スクロールの処理はPanelのAutoScrollに任せて、一切コードは書かなくても大丈夫のはずです。

投稿2019/05/27 11:38

編集2019/05/28 02:14
YAmaGNZ

総合スコア10258

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

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

0

PictureBox から Graphics を作るのではなく、PictureBox.Image から Graphics を作り、そこに描いてください。

Form1.cs

C#

1using System; 2using System.Drawing; 3using System.Windows.Forms; 4 5namespace WindowsFormsApp1 6{ 7 public partial class Form1 : Form 8 { 9 public Form1() 10 { 11 InitializeComponent(); 12 } 13 14 private void PictureBox1_SizeChanged(object sender, EventArgs e) 15 { 16 var image = pictureBox1.Image; 17 if (image != null && image.Height == pictureBox1.ClientSize.Height) 18 { 19 return; 20 } 21 if (pictureBox1.ClientSize.Height <= 0) 22 { 23 pictureBox1.Image = null; 24 return; 25 } 26 image = new Bitmap(1000, pictureBox1.ClientSize.Height); 27 using (var graphics = Graphics.FromImage(image)) 28 using (var brush = new SolidBrush(Color.Blue)) 29 { 30 graphics.FillEllipse(brush, new Rectangle(new Point(0, 0), image.Size)); 31 } 32 pictureBox1.ClientSize = image.Size; 33 pictureBox1.Image = image; 34 } 35 } 36} 37

Form1.Designer.cs

C#

1namespace WindowsFormsApp1 2{ 3 partial class Form1 4 { 5 /// <summary> 6 /// 必要なデザイナー変数です。 7 /// </summary> 8 private System.ComponentModel.IContainer components = null; 9 10 /// <summary> 11 /// 使用中のリソースをすべてクリーンアップします。 12 /// </summary> 13 /// <param name="disposing">マネージ リソースを破棄する場合は true を指定し、その他の場合は false を指定します。</param> 14 protected override void Dispose(bool disposing) 15 { 16 if (disposing && (components != null)) 17 { 18 components.Dispose(); 19 } 20 base.Dispose(disposing); 21 } 22 23 #region Windows フォーム デザイナーで生成されたコード 24 25 /// <summary> 26 /// デザイナー サポートに必要なメソッドです。このメソッドの内容を 27 /// コード エディターで変更しないでください。 28 /// </summary> 29 private void InitializeComponent() 30 { 31 this.pictureBox1 = new System.Windows.Forms.PictureBox(); 32 ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); 33 this.SuspendLayout(); 34 // 35 // pictureBox1 36 // 37 this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Left; 38 this.pictureBox1.Location = new System.Drawing.Point(0, 0); 39 this.pictureBox1.Name = "pictureBox1"; 40 this.pictureBox1.Size = new System.Drawing.Size(100, 253); 41 this.pictureBox1.TabIndex = 0; 42 this.pictureBox1.TabStop = false; 43 this.pictureBox1.SizeChanged += new System.EventHandler(this.PictureBox1_SizeChanged); 44 // 45 // Form1 46 // 47 this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F); 48 this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 49 this.AutoScroll = true; 50 this.ClientSize = new System.Drawing.Size(282, 253); 51 this.Controls.Add(this.pictureBox1); 52 this.Name = "Form1"; 53 this.Text = "Form1"; 54 ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); 55 this.ResumeLayout(false); 56 57 } 58 59 #endregion 60 61 private System.Windows.Forms.PictureBox pictureBox1; 62 } 63}

投稿2019/05/27 11:26

Zuishin

総合スコア28660

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

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

退会済みユーザー

退会済みユーザー

2019/06/03 07:48

Zuishin←コイツ https://teratail.com/questions/192606 ↑Zuishinの本性、発言内容。コイツが修正しない限り、コメントが残っている事だろう。修正しない限りは。 コイツは、「電話してやる、ビビってるのか?」などと私を煽り、ネットでしかイキがれないクズなのだが、いざ私が電話番号を教えてやったら、「書いたね。ご苦労さん。あとは好きなだけ吠えてろ」と、逃げる腐れ外道であり、精神疾患患者である。 こう言うゴミが生きてる事自体が許せない。皆さんもコイツには気をつけましょう。
Q71

2019/06/03 08:09

> PictureBox.Image から Graphics を作り PictureBox.Image に割り当てた Image オブジェクトから Graphics を作り、かなぁ。 描画のたびに新たに Image を作るのもひとつ。
Zuishin

2019/06/03 08:13

そうですね。描画のたびにというのもパフォーマンスが悪くなりそうなので、私のコードではウィンドウのサイズ変更で画像を作っています。
guest

0

ちらつきをなくすだけなら、フォームのプロパティにある、
DoubleBuffered を trueにするといいと思います

投稿2019/05/27 02:49

izmktr

総合スコア2856

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

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

kemomimi_sabal

2019/05/27 03:13

Panelの上にHscrollとVScrollを個別に置いています
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問