C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

C# PictureBoxクリックで画像切り替えが遅い…

[トピック内 8 記事 (1 - 8 表示)]  << 0 >>

■88341 / inTopicNo.1)  C# PictureBoxクリックで画像切り替えが遅い…
  
□投稿者/ 無理ゲー (9回)-(2018/08/22(Wed) 12:17:07)

分類:[C#] 

環境【VS2017】

6枚の画像を順番にクリックで表示切り替えを下のように書いてみたのですが、
クリック反応がどうも遅い感じがします。どのようにすれば良いのかアドバイスください。
初心者なのでお手柔らかにお願いいたします。。。。
間違ってる所があったらスミマセン。。。。

int clickCount;

        private void Format_Picture_Click(object sender, EventArgs e)
        {

            clickCount++;

            switch (clickCount)
            {
                case 1:
                    Format_Picture.Image = Properties.Resources.Format_1;
                    break;
                case 2:
                    Format_Picture.Image = Properties.Resources.Format_2;
                    break;
                case 3:
                    Format_Picture.Image = Properties.Resources.Format_3;
                    break;
                case 4:
                    Format_Picture.Image = Properties.Resources.Format_4;
                    break;
                case 5:
                    Format_Picture.Image = Properties.Resources.Format_5;
                    break;
                case 6:
                    Format_Picture.Image = Properties.Resources.Format_6;
                    clickCount = 0;
                    break;
            }
        }

引用返信 編集キー/
■88345 / inTopicNo.2)  Re[1]: C# PictureBoxクリックで画像切り替えが遅い…
□投稿者/ furu (182回)-(2018/08/22(Wed) 12:48:39)
No88341 (無理ゲー さん) に返信
> 環境【VS2017】
>
> 6枚の画像を順番にクリックで表示切り替えを下のように書いてみたのですが、
> クリック反応がどうも遅い感じがします。どのようにすれば良いのかアドバイスください。

いろいろと大変なんじゃない。

試していないけど、Format_Picture同じの6個用意して
Hide,Showだと早くならないかな。
引用返信 編集キー/
■88348 / inTopicNo.3)  Re[1]: C# PictureBoxクリックで画像切り替えが遅い…
□投稿者/ 魔界の仮面弁士 (1790回)-(2018/08/22(Wed) 13:23:49)
No88341 (無理ゲー さん) に返信
> Format_Picture.Image = Properties.Resources.Format_1;

Image a = Properties.Resources.Format_1;
Image b = Properties.Resources.Format_1;

とした場合、a == b になるかのように思えますが、
実際には別々のインスタンスになりますのでご注意を。

今回のような場合には、private Image[] images; なフィールド変数などに
6 画像すべてを取り込んでおき、それを差し替えた方が良いでしょう。


なお、リソース画像の取得には、
Image c = Resources.ResourceManager.GetObject("Format_1") as Image;
という構文を用いることもできます。


それと Image である以上、本来は不要になった時点で Dispose を呼ぶ必要があります。
ガベージコレクト任せにする手段もありますが、廃棄と再生成を頻繁に行う場合には向きません。
ただし private Image[] images; などに蓄えて使いまわすのであれば、
画面表示中に Dispose を呼ぶ必要はありません。(アプリ終了時の処分だけで済む)
引用返信 編集キー/
■88350 / inTopicNo.4)  Re[2]: C# PictureBoxクリックで画像切り替えが遅い…
□投稿者/ にゃるら (34回)-(2018/08/22(Wed) 13:43:26)
魔界の仮面弁士さんの言うことを試してみようと思って以下のように書いてみました。

環境はWin7(64bit)、VisualStudio2017、.Net4.6.1、C#です。
画像はResources.resxを開いて、リソースの追加でImage6個分を1〜6の文字を書いたもので作成しました。

自分の結果としては反応がいまいちでした。
SizeModeがStretchImageなのが悪いのかもとNormalにしてもあまり変化はありませんでした。

PictureBoxを使わない方がよいのかな?


using System;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        /// <summary>
        /// コンストラクタ
        /// </summary>
        public Form1()
        {
            InitializeComponent();

            this.imgtable = new Image[] {
                Properties.Resources.Image1,
                Properties.Resources.Image2,
                Properties.Resources.Image3,
                Properties.Resources.Image4,
                Properties.Resources.Image5,
                Properties.Resources.Image6,
            };

            ReplaceImage();
        }

        /// <summary>
        /// 必要なデザイナー変数です。
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        #region Windows フォーム デザイナーで生成されたコード

        /// <summary>
        /// デザイナー サポートに必要なメソッドです。このメソッドの内容を
        /// コード エディターで変更しないでください。
        /// </summary>
        private void InitializeComponent()
        {
            this.pictureBox1 = new System.Windows.Forms.PictureBox();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
            this.SuspendLayout();
            // 
            // pictureBox1
            // 
            this.pictureBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
            | System.Windows.Forms.AnchorStyles.Left)
            | System.Windows.Forms.AnchorStyles.Right)));
            this.pictureBox1.Location = new System.Drawing.Point(34, 28);
            this.pictureBox1.Name = "pictureBox1";
            this.pictureBox1.Size = new System.Drawing.Size(721, 397);
            this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
            this.pictureBox1.TabIndex = 0;
            this.pictureBox1.TabStop = false;
            this.pictureBox1.Click += new System.EventHandler(this.pictureBox1_Click);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(800, 450);
            this.Controls.Add(this.pictureBox1);
            this.Name = "Form1";
            this.Text = "Form1";
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.PictureBox pictureBox1;

        /// <summary>
        /// 使用中のリソースをすべてクリーンアップします。
        /// </summary>
        /// <param name="disposing">マネージ リソースを破棄する場合は true を指定し、その他の場合は false を指定します。</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }

            if (this.imgtable != null)
            {
                foreach (var img in this.imgtable)
                {
                    img?.Dispose();
                }
                this.imgtable = null;
            }

            base.Dispose(disposing);
        }

        private Image[] imgtable;
        private int ClickCount = 0;

        private void pictureBox1_Click(object sender, EventArgs e)
        {
            ++ClickCount;
            ReplaceImage();
        }

        private void ReplaceImage()
        {
            if (this.imgtable != null)
            {
                var index = ClickCount % this.imgtable.Length;
                this.pictureBox1.Image = imgtable[index];
            }
        }
    }
}

引用返信 編集キー/
■88352 / inTopicNo.5)  Re[3]: C# PictureBoxクリックで画像切り替えが遅い…
□投稿者/ にゃるら (35回)-(2018/08/22(Wed) 13:57:09)
No88350 (にゃるら さん) に返信

Clickイベントではなく、MouseDownイベントで処理したら早くなった気がします。


引用返信 編集キー/
■88353 / inTopicNo.6)  Re[1]: C# PictureBoxクリックで画像切り替えが遅い…
□投稿者/ 魔界の仮面弁士 (1792回)-(2018/08/22(Wed) 14:10:15)
No88341 (無理ゲー さん) に返信
> クリック反応がどうも遅い感じがします。どのようにすれば良いのかアドバイスください。

ダブルクリックを禁止してみる

public class PictureBoxEx : PictureBox
{
 public PictureBoxEx()
 {
  SetStyle(ControlStyles.StandardDoubleClick, false);
  DoubleBuffered = true;
 }
}
引用返信 編集キー/
■88354 / inTopicNo.7)  Re[4]: C# PictureBoxクリックで画像切り替えが遅い…
□投稿者/ 無理ゲー (11回)-(2018/08/22(Wed) 14:30:51)
魔界の仮面弁士さん
にゃるらさん

出来ました^^
ご丁寧にコードまで書いて頂いてありがとうございました。
解決済み
引用返信 編集キー/
■88355 / inTopicNo.8)  Re[2]: C# PictureBoxクリックで画像切り替えが遅い…
□投稿者/ にゃるら (36回)-(2018/08/22(Wed) 14:34:41)
2018/08/22(Wed) 14:35:01 編集(投稿者)
No88353 (魔界の仮面弁士 さん) に返信
> ■No88341 (無理ゲー さん) に返信
>>クリック反応がどうも遅い感じがします。どのようにすれば良いのかアドバイスください。
> 
> ダブルクリックを禁止してみる

なるほど、
  クリック1回目:クリックイベント
  クリック2回目:ダブルクリックイベント
  クリック3回目:クリックイベント
  クリック4回目:ダブルクリックイベント
  クリック5回目:クリックイベント
  クリック6回目:ダブルクリックイベント
  ・・・
となっていたから「反応しない」ように見えたということだったんですね。
処理が重いとかの理由ではなかったんですね。

解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ