none
コントロール名の最後に数字の連番があるコントロールをループで処理する方法 RRS feed

  • 質問

  • visual c# 2010を利用しています。

    過去の質問をいろいろ調べましたが解決にいたりませんでしたの質問させていただきます。

    フォーム上に、dateTimePickerのコントロールが、10個ならんでおりそれぞれに、dateTimePickerBox1、dateTimePickerBox2、・・・・・dateTimePickerBox10

    と名前がついています。

    このコントロールに、現在の日時に関する情報をfor文でセットするためのコードの記載方法についてお教えください。

    for (int i = 1; i <= 10; i++)

    {

    //この位置に、dateTimePickerBox1、dateTimePickerBox2、・・・・・dateTimePickerBox10のそれぞれに、

    //DateTime.Now;の値をループ処理でセットする。

    HPで検索すると、配列を作って処理する方法等が紹介されておりますが、バージョンの影響等かうまくいきません。

    どうかよろしくお願いします。

     

     

     

    2011年6月24日 4:57

回答

  • dateTimePickerBoxは、Form1.cs[デザイン]* のフォームプロパティの(Name)で、dateTimePickerBox1、dateTimePickerBox2・・・dateTimePickerBox10

    と定義しております。 

     Nameプロパティに指定する値がクラス名になります。したがって、dateTimePickerBox1、dateTimePickerBox2・・・dateTimePickerBox10それぞれが、各DateTimePickerのクラス名になります。
    また、

    >dateTimePickerBoxは、Form1.cs[デザイン]* のフォームプロパティの(Name)

    と書かれていますが、正しくは、「Form1に配置されている各DateTimePickerのNameプロパティのそれぞれに、dateTimePickerBox1、dateTimePickerBox2・・・dateTimePickerBox10と指定しています。」といった表現になります。(おそらくそれぞれの名前は自動的に名付けられたものをそのまま採用されているのだと思いますが)

     

    そして、Form1.cs*コードの中で、dateTimePickerBox[] dateTimePickerBoxArray;として記述しています。 

    上記は、dateTimePickerBoxというクラス(型)の配列を宣言しようとしていますが、dateTimePickerBoxという型はどこにも無いために見つからないと言われています。dateTimePickerBox1、dateTimePickerBox2・・・dateTimePickerBox10のどれとも違いますよね。
    ではどうすればいいのでしょうか?dateTimePickerBox1、dateTimePickerBox2・・・dateTimePickerBox10を格納するための配列の型はどのように宣言すれば良いのでしょうか? 入れたいものは10種類のそれぞれの型です。しかし、配列を宣言する時に指定できるのは1つの型だけです。
    少し難しい話になるかもしれませんが、10種類と言っても全てDateTimePickerです。実は、dateTimePickerBox1、dateTimePickerBox2・・・dateTimePickerBox10は全てDateTimePickerというクラス(型)から派生したクラス(型)なのです。このように派生していれば、キャストと言って、派生元のクラス(型)としても扱うことができます。よって、DateTimePicker型の配列を定義すれば、この中にdateTimePickerBox1、dateTimePickerBox2・・・dateTimePickerBox10を入れることができるようになります。

    DateTimePicker[] dateTimePickerBoxArray;

    >usingを使って名前空間を指定するか、名前空間を含めて(名前空間で修飾して)dateTimePickerBoxを記述してみて下さい。

    の部分について、もう少し詳しくお教えお願いしたいと思います。

    以下にわかりやすく解説されていますので、ご覧ください。

    名前空間
    http://ufcpp.net/study/csharp/sp_namespace.html

     

    C#の学習をはじめられたばかりなのでいろいろな疑問点をお持ちだと思いますが、幸いネットにはたくさんの良い記事があります。書籍もたくさんありますので、それらを参考に是非楽しんで下さい。クラスやオブジェクト指向は最初は取っ付き難いものですので、また疑問があればご質問下さい。

     


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    • 回答としてマーク hanahana87 2011年6月26日 1:55
    2011年6月25日 2:57
    モデレータ
  • こんにちは、アイライトの石野です。

    Windows.Formsなら、this.Controlsを使えば簡単にできると思います。

    for (int index = 1; index <= 3; index++)

    ((DateTimePicker)this.Controls[string.Format("dateTimePicker{0}", index)]).Value = DateTime.Today;
    }

    こんな感じでしょうか?

    • 回答としてマーク hanahana87 2011年6月24日 7:57
    • 回答としてマークされていない hanahana87 2011年6月24日 7:58
    • 回答としてマーク hanahana87 2011年6月24日 8:03
    2011年6月24日 6:53

すべての返信

  • 以下のような記載をしています。

    public struct alarm
            {
                public bool alarmEnabled;
                public DateTime alarmtime;
                public string alarm_Message;

    public string state;
             }

            alarm[] alarmdata;
            int count, maxindex = 10;

    dateTimePickerBox[] dateTimePickerBoxArray;     //(1)dateTimePickerBoxでエラー

    public Form1()
            {
                InitializeComponent();
            }

            private void Form1_Load(object sender, EventArgs e)
            {
                label1.Text = DateTime.Now.ToString("yyyy年 MM月 dd日 (ddd)  HH時   mm分   ss秒");

                //テキストボックスコントロールの配列を作成する
                dateTimePickerBoxArray = (dateTimePickerBox[])GetControlArrayByName(this, "dateTimePickerBox");   //(2)dateTimePickerBoxでエラー

    alarmdata = new alarm[maxindex];
                for (int i = 0; i < maxindex; i++)
                {
                    alarmdata[i].alarmEnabled = false;
                    alarmdata[i].adate = DateTime.Now;
                    alarmdata[i].state = "未設定";

                    dateTimePickerBoxArray[i].Value = alarmdata[i].adate;    //(3)

    //(1)及び(2)のところで次のエラーとなります。

    エラー 1 型または名前空間名 'dateTimePickerBox' が見つかりませんでした。using ディレクティブまたはアセンブリ参照が不足しています。

     

    //(3)のところで

    この記述をループの中(forの中)に入れずに、次のように記述するとエラーになりませんが、

    dateTimePickerBox1.Value = alarmdata[0].adate;
                dateTimePickerBox2.Value = alarmdata[1].adate;
                dateTimePickerBox3.Value = alarmdata[2].adate;

    ・・・・

    //(3)のようにループに入れると型変換のエラーになります。

    なお、GetControlArrayByNameは、省略していますが、コントロールの配列を取得するものです。

    よろしくお願いします。

     

    2011年6月24日 5:45
  • こんにちは、アイライトの石野です。

    Windows.Formsなら、this.Controlsを使えば簡単にできると思います。

    for (int index = 1; index <= 3; index++)

    ((DateTimePicker)this.Controls[string.Format("dateTimePicker{0}", index)]).Value = DateTime.Today;
    }

    こんな感じでしょうか?

    • 回答としてマーク hanahana87 2011年6月24日 7:57
    • 回答としてマークされていない hanahana87 2011年6月24日 7:58
    • 回答としてマーク hanahana87 2011年6月24日 8:03
    2011年6月24日 6:53
  • 石野様
    佐祐理様

    ご指導ありがとうございます。
    石野様よりお教えいただきました方法でプログラムを実行することが
    できました。
    コードについては、これから研究させていただきます。
    C#については、まだ始めて間もないものですが、皆様のおかげで好き
    になれそうです。
    今後とも、よろしくお願いいたします。

    2011年6月24日 8:03
  • 解決されたのは良いのですが、できれば今後のために最初のコードのエラーを取ることもがんばってみて下さい。

    >エラー 1 型または名前空間名 'dateTimePickerBox' が見つかりませんでした。using ディレクティブまたはアセンブリ参照が不足しています。

    このエラーは最も基本的なエラーの一つです。dateTimePickerBoxはどこで定義されていますか?コンパイラが見つけることができないようです。もしどこかに定義されているのであれば、usingを使って名前空間を指定するか、名前空間を含めて(名前空間で修飾して)dateTimePickerBoxを記述してみて下さい。よくわからなければ、エラーメッセージにも出ていますが「名前空間」を調べてみて下さい。

    >dateTimePickerBoxArray[i].Value = alarmdata[i].adate;    //(3)

    このエラーに関してもdateTimePickerBoxが関連していると思われますので、まずは前述のエラーを取るようにして下さい。

    この先、C#で開発を進めるのであれば、名前空間は最も基本的な事柄の一つであり、かつ、最も使用するものの一つです。ですから、名前空間をきちんと理解されないまま先に進まれることが気になりました。

     


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    2011年6月24日 8:35
    モデレータ
  • trapemiyaさま

    ご教授ありがとうございます。

    コメントいただきましたとおり、自身としてもこのエラーの原因を理解して修正していかなければC#の本当の理解はできないと思っており、気になっているところです。

    dateTimePickerBoxは、Form1.cs[デザイン]* のフォームプロパティの(Name)で、dateTimePickerBox1、dateTimePickerBox2・・・dateTimePickerBox10

    と定義しております。

    そして、Form1.cs*コードの中で、dateTimePickerBox[] dateTimePickerBoxArray;として記述しています。

    ご指摘のとおり、このコードの、dateTimePickerBox[] の部分のソースには赤の波下線が表示されて、先のエラーメッセージが表示されています。

    名前空間については、

    namespace アラーム時計

    を記述しており、dateTimePickerBox[] dateTimePickerBoxArray;はその中にあります。

    よろしければ、

    >usingを使って名前空間を指定するか、名前空間を含めて(名前空間で修飾して)dateTimePickerBoxを記述してみて下さい。

    の部分について、もう少し詳しくお教えお願いしたいと思います。

    よろしくお願いします。

     

    2011年6月25日 1:35
  • 自己レスで失礼します。

    そして、皆様ありがとうございます。

    名前空間を調べて以下のとおり解決できました。

    dateTimePickerBoxは新たに定義したものではなく、元から備わっている dateTimePickerを使いたいものでした。

    よって、以下のとおり修正しました。

    (誤) dateTimePickerBox[] dateTimePickerBoxArray;

    (正) dateTimePicker[] dateTimePickerBoxArray;

     

    (誤) dateTimePickerBoxArray = (dateTimePickerBox[]) GetControlArrayByName(this, "dateTimePickerBox");

    (正) dateTimePickerBoxArray = (dateTimePicker[]) GetControlArrayByName(this, "dateTimePickerBox");

     

    利用する場合の、dateTimePickerBoxArray[i].Value = alarmdata[i].adate;

    はそのままです。

    ありがとうございました。

     

    2011年6月25日 2:42
  • dateTimePickerBoxは、Form1.cs[デザイン]* のフォームプロパティの(Name)で、dateTimePickerBox1、dateTimePickerBox2・・・dateTimePickerBox10

    と定義しております。 

     Nameプロパティに指定する値がクラス名になります。したがって、dateTimePickerBox1、dateTimePickerBox2・・・dateTimePickerBox10それぞれが、各DateTimePickerのクラス名になります。
    また、

    >dateTimePickerBoxは、Form1.cs[デザイン]* のフォームプロパティの(Name)

    と書かれていますが、正しくは、「Form1に配置されている各DateTimePickerのNameプロパティのそれぞれに、dateTimePickerBox1、dateTimePickerBox2・・・dateTimePickerBox10と指定しています。」といった表現になります。(おそらくそれぞれの名前は自動的に名付けられたものをそのまま採用されているのだと思いますが)

     

    そして、Form1.cs*コードの中で、dateTimePickerBox[] dateTimePickerBoxArray;として記述しています。 

    上記は、dateTimePickerBoxというクラス(型)の配列を宣言しようとしていますが、dateTimePickerBoxという型はどこにも無いために見つからないと言われています。dateTimePickerBox1、dateTimePickerBox2・・・dateTimePickerBox10のどれとも違いますよね。
    ではどうすればいいのでしょうか?dateTimePickerBox1、dateTimePickerBox2・・・dateTimePickerBox10を格納するための配列の型はどのように宣言すれば良いのでしょうか? 入れたいものは10種類のそれぞれの型です。しかし、配列を宣言する時に指定できるのは1つの型だけです。
    少し難しい話になるかもしれませんが、10種類と言っても全てDateTimePickerです。実は、dateTimePickerBox1、dateTimePickerBox2・・・dateTimePickerBox10は全てDateTimePickerというクラス(型)から派生したクラス(型)なのです。このように派生していれば、キャストと言って、派生元のクラス(型)としても扱うことができます。よって、DateTimePicker型の配列を定義すれば、この中にdateTimePickerBox1、dateTimePickerBox2・・・dateTimePickerBox10を入れることができるようになります。

    DateTimePicker[] dateTimePickerBoxArray;

    >usingを使って名前空間を指定するか、名前空間を含めて(名前空間で修飾して)dateTimePickerBoxを記述してみて下さい。

    の部分について、もう少し詳しくお教えお願いしたいと思います。

    以下にわかりやすく解説されていますので、ご覧ください。

    名前空間
    http://ufcpp.net/study/csharp/sp_namespace.html

     

    C#の学習をはじめられたばかりなのでいろいろな疑問点をお持ちだと思いますが、幸いネットにはたくさんの良い記事があります。書籍もたくさんありますので、それらを参考に是非楽しんで下さい。クラスやオブジェクト指向は最初は取っ付き難いものですので、また疑問があればご質問下さい。

     


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    • 回答としてマーク hanahana87 2011年6月26日 1:55
    2011年6月25日 2:57
    モデレータ
  • 名前空間についておさらいいたしました。

    言葉の定義もそこそに、実際にプログラムを作っていたので基本的なことが学べていなかったようです。

    実際に作りながら、そして文法などの基本も並行して勉強していきたいと思います。

    次は、プログラム上のデータの記録として、ファイルの書き出しと読み出しの部分に入る予定です。

    いろいろな、エラーに悩まされると思っていますが、作るのが今からたのしみです。

    また、疑問に遭遇しましたときには、質問させていただきますのでこれからもよろしくお願いします。

    皆様、ありがとうございました。

    2011年6月25日 9:59
  • で、最初の私の返信に戻るんですが、Controlsプロパティを使用するよりも、コントロールの配列を作成することをお勧めします。

    2011年6月25日 10:11
  • これまでお教えいただきました方法で、大きな流れとしては以下のようにしました。
    (1)(2)(3)の部分は、配列を利用したものといえるでしょうか。

    public partial class Form1 : Form
    {
     //途中省略
     public struct alarm
     {
                public bool alarmEnabled;
                public bool alarmEveryday;
                public DateTime adate;
                public DateTime dateTimePickerBox;

                public DateTime alarmtime;
                public string alarmhourminute;
                public int ahour;
                public int aminute;

                public string alarm_Message;
                public string alarmSound;
                public string state;
     }
     
     alarm[] alarmdata;
     int count, maxindex = 10;

     DateTimePicker[] dateTimePickerBoxArray; //(1)

     //途中省略

     private void Form1_Load(object sender, EventArgs e)
     {
              //途中省略
              //"dateTimePickerBox"の連続したNameを取得する関数
              dateTimePickerBoxArray = (DateTimePicker[])GetControlArrayByName(this, "dateTimePickerBox"); //(2)
            
              alarmdata = new alarm[maxindex];
              for (int i = 0; i < maxindex; i++)
                 {
                      alarmdata[i].adate = DateTime.Now;
                     dateTimePickerBoxArray[i].Value = alarmdata[i].adate; //(3)
                 }

              //途中省略
     }
     //途中省略
    }

    2011年6月25日 13:24