コントロール配列を使わずに

タグの編集
投稿者 VB6から脱皮できない者  (社会人) 投稿日時 2009/12/20 04:54:39
VB2008EXPRESSを最近学び始めたました。
VB6のようなコントロール配列がないと知り、ヘルプ等を見ながら
非常に面倒な長いコードを書きながら、シンプルにできないか悩みながら考えています。
なかなか光明が見えないので、一つだけヒントをいただきたいと思い、投稿しました。
例えば、PictureBox1.Image = ABC.Image
       PictureBox2.Image = ABC.Image
       中略
       PictureBox9.Image = ABC.Image
       PictureBox10.Image = ABC.Image
ABC.Imageを10個のPictureBoxに入れようとすると、このように同じことを10回記述せず、
簡単にできないものですしょうか。
よろしくお願いします。
投稿者 daive  (社会人) 投稿日時 2009/12/20 06:02:23
こちらの、過去の書き込みにも有ったはずですが、

1.Me.Controls について調べてみてください。
  ついでに、
  Me.Controls.Find
  Me.Controls(xxxx).Controls(xxxxx)
  などについても、   
2.Me.Controls が解れば、Control オブジェクトを
  配列に入れられる事も解る筈です。
  →で、結果、使い慣れれば、
   VB6のコントロール配列より自由度が上がっています。
   関連オブジェクトを、配列に入れて、、、という使い方とか。

3.あくまで、VB6方式に拘る場合は、
  VB6で、コントロール配列を作って、
  アップグレードしてみてください。
  ウィザードでの、コントロール配列の実現方法が、
  解ります。
投稿者 neptune  (社会人) 投稿日時 2009/12/20 06:06:09
過去ログにサンプルコードがありますから、それ見て研究しては如何?
ちなみに、VB6と同じやり方と、vb.net以降のやり方のサンプルがあります。
いずれにしても長いコードにはなりますが。

又、「コントロール配列」をキーワードに過去ログを検索すると複数ヒットしますので
それも読んで見ましょう。
投稿者 neptune  (社会人) 投稿日時 2009/12/20 06:06:59
URL忘れてました。
http://rucio.groupsite.jp/commu/ThreadDetail.aspx?ThreadId=9086
投稿者 VBから脱皮できない者  (社会人) 投稿日時 2009/12/20 06:30:18
neptuneさん、daiveさん
ありがとうございました。
ヘルプを参考にしようとしたのですが、
いまいち、確信がもてなくて・・・
アドバイスをいただいた点をもとに
じっくりと取り組んでいこうと思います。
ホントに助かりました。
投稿者 るしぇ  (社会人) 投稿日時 2009/12/20 18:14:53
> URL忘れてました。
> http://rucio.groupsite.jp/commu/ThreadDetail.aspx?ThreadId=9086 

> 投稿者 魔界の仮面弁士   (社会人)   投稿日時 2009/04/22 10:32:24
で紹介されていますが、
http://dobon.net/vb/dotnet/control/buttonarray.html
の2番目の方法のように、デザイン画面のコントロールを
コントロールの配列に入れるのは初心者でもすぐにできる
簡単な方法ですね。
コントロール数が多いとそこそこ長くはなるけど、長いと
言うほどでは無いと思います。Excel を使えば連番を振る
ようなコードは簡単に大量生産できますし。
投稿者 るきお  (社会人) 投稿日時 2009/12/20 22:31:58
入門者はしょうがないなぁ。
コンストラクタのつくりかたとか、本を買え。
質問を1個クリアしても次々と壁にぶつかるんでキリがない。
基礎をやれ。
投稿者 cupic  (社会人) 投稿日時 2009/12/21 06:32:53
確かに基礎は大事ですね。まず既存の(手持ちの)アプリケーションを忘れて、
基本的な所から始めてはいかがでしょうか。まずフォームとその部品、ラベル、
テキストBox、ボタン、リストBox、ピクチャBox、こんなものですか。次に、
ファイルの読み書き、etc。以降は好みや関心テーマに分かれますから、人それ
ぞれ、自分の場合はグラフィック表示、つまり線画ドローやポリゴン塗り潰しが
至上命題でしたからそちらを追求しました。VB6はLineメソッド位だったけど、
DotNetでは、Drawlineその他グラフィック機能豊富で、もうVB6には戻れない
気分になりましたよ。ただFileI/Oもグラフィック表示もVB6とはかなり異なる
部分で、いくらか難儀した気もします。

次に、多少、人と異なる考えかもしれませんが、ボクはソフト関連の本は嫌いで、
開発ツールそのもののHelp頼みです。全くの初心者なら入門書や講義を聞くのは
良いかもしれませんが、多少なりとも他言語の経験あるなら、Helpから芋づるで
調べるのが良いと思います。また、upGradeウィーザードはお勧めしませんよ。
あれは、普通そのままでは動かず、動かす為にはVB.Netの知識が必須ですから、
自己矛盾に陥ります。だから最初は基礎からです。
投稿者 あにす  (社会人) 投稿日時 2009/12/21 07:42:27
いや待ってそのるきおさんどう考えても騙りでしょう?
投稿者 るきお  (社会人) 投稿日時 2009/12/21 18:08:09
2009/12/20 13:31:58 の投稿は私ではありません。
投稿者 るきお  (社会人) 投稿日時 2009/12/21 21:59:52
今回の件は以下の記事でも取り上げていますのでよろしければ参考にしてください。
初級講座第20回 コントロールをまとめる方法
http://homepage1.nifty.com/rucio/main/dotnet/shokyu/standard20.htm

2008ならこんな書き方もあります。
(環境が手元にないので試していません。間違っていたら失礼。考え方はあっています。)
 
For Each pb In Me.Controls.OfType(Of PictureBox)
    pb.Image = ACB.Image
Next 


あるいは、

 
For Each pb In Me.Controls.OfType(Of PictureBox)
    If pb.Name.StartWith("PictureBox"Then
        pb.Image = ACB.Image
    End If
Next 


などです。

daiveさんの投稿日時 2009/12/19 21:02:23 の1の方法が真っ先に浮かぶのですが、
Me.Controls("PictreBox" & i).Image = …
と書くとImageはControlのメンバでありませんという警告が出るのが嫌なんです。
もちろんCTypeやDirectCaseで型変換すれば警告もクリアできますが、
ちょっと敷居が高いですよね。

いずれにせよ、コンテナが間に入っている場合を考慮する必要もあります。
もっと敷居が低くていい方法はないでしょうか?

投稿者 るしぇ  (社会人) 投稿日時 2009/12/21 22:54:36
> いずれにせよ、コンテナが間に入っている場合を考慮する必要もあります。
> もっと敷居が低くていい方法はないでしょうか?
ボクの答えは前述通りです。
コントロールの配列にデザイン画面のコントロールを1つ1つ設定しておきます。
投稿者 るきお  (社会人) 投稿日時 2009/12/22 03:05:55
>コントロールの配列にデザイン画面のコントロールを1つ1つ設定しておきます。
参照先も含めていろいろな方法が挙がっていますが、
結局は私もこの1つ1つ設定する方法をまずはお勧めすることにすると思います。

ただ、.NETを始めたばかりのころは私もコントロール配列がないのがやりにくく思ったのが、
今はとくに不便を感じないようになりました。
原因はよくわかりませんが、コントロール配列がないことがわかっているので、
(書面にせよ頭の中にせよ)設計段階で無意識にコントロール配列なし前提のものを
考えるようになっているのかもしれません。

余談ですがVB2010では次のような書き方ができます。

Dim thisImage = Image.FromFile("C:\Windows\隅田川.bmp")

Me.Controls.OfType(Of PictureBox).All(Function(pic)
                                          pic.Image = thisImage
                                          Return True
                                      End Function)

これで引数のFunction内でIfなどで切り分けるロジックを書けばかなり柔軟に対応できそうです。
(でも、実際の業務ではこんなコードは書くかどうか微妙です。)
投稿者 かも健。。壱  (小学生) 投稿日時 2009/12/22 05:17:45
だから解説が高度なんで質問者は理解でましぇんよ。
この質問者は、あきらかに入門者。
基礎の1番最初のあたりからガンバルしかない。
冷たいようだが、基礎をやれ。とゆうのは1番の早道である。
Public Class Form1
    'フォームにpictureBoxを10個入れる。 
    '入門用www_ほぇ~。 
    '入門者はコードでコントロールを作るな。ハハハ 
    '背伸びをするな。基礎をやれ。 
    Dim my_pictureBox_kazu As Integer = 10
    Dim my_pictureBox(my_pictureBox_kazu - 1) As PictureBox
    Private Sub Form1_Load(ByVal sender As ObjectByVal e As System.EventArgs) Handles Me.Load
        my_pictureBox(0) = PictureBox1
        my_pictureBox(1) = PictureBox2
        my_pictureBox(2) = PictureBox3
        my_pictureBox(3) = PictureBox4
        my_pictureBox(4) = PictureBox5
        my_pictureBox(5) = PictureBox6
        my_pictureBox(6) = PictureBox7
        my_pictureBox(7) = PictureBox8
        my_pictureBox(8) = PictureBox9
        my_pictureBox(9) = PictureBox10
        For i As Integer = 0 To my_pictureBox_kazu - 1
            my_pictureBox(i).BackColor = Color.Blue
            my_pictureBox(i).Size = New Size(10, 10)
            my_pictureBox(i).Location = New Point(30 + i * 20, 30)
            AddHandler my_pictureBox(i).Click, AddressOf my_pictureBox_click
        Next
    End Sub
    Private Sub my_pictureBox_click(ByVal sender As ObjectByVal e As EventArgs)
        MessageBox.Show(CType(sender, System.Windows.Forms.PictureBox).Name)
    End Sub
End Class
投稿者 VBから脱皮できない者  (社会人) 投稿日時 2009/12/23 08:30:47
数日間、研究していて掲示板を見ていなかったんですが、
皆さんから叱咤激励を頂戴しましてありがとうございます。
基礎から学ぶ、ボチボチやろうと思っています。他人から
学ばせていただくことも多く、勉強になります。
とちあえず、プログラムとしてはどうかわかりませんが、
現在、自分なりに次のように記述して、1歩前に進んでいます。
For Me.i = 1 To 20 
  DirectCast(Me.Controls.Item("PictureBox" & i), PictureBox).Image = ABC.Image
Next
いまいち、わからない部分もあるのですが、少しずつ歩いていきます。
アドバイスをいただいた方、どうもありがとうございました。
投稿者 (削除されました)  () 投稿日時 2009/12/23 17:00:42
(削除されました)
投稿者 (削除されました)  () 投稿日時 2009/12/24 02:26:17
(削除されました)
投稿者 (削除されました)  () 投稿日時 2009/12/24 03:53:01
(削除されました)
投稿者 cupid  (社会人) 投稿日時 2009/12/24 18:13:26
ソフト専業や趣味以外で、つまり手段としてソフト作るような場合は、
DotNetは疑問ですね。精力を取られすぎる過ぎるから。
あくまでも個人的な感想ですよ。VBAやVBSも活用する方が良いのでは。
少なくとも、VB6のCDと最新サービスパックは温存して置くべきでしょう。
投稿者 るしぇ  (社会人) 投稿日時 2009/12/24 19:30:07
>VBから脱皮できない者 
VB6じゃ無かったんですか。。。???

>ソフト専業や趣味以外で、つまり手段としてソフト作るような場合は、
>DotNetは疑問ですね。精力を取られすぎる過ぎるから。
それだけで済むなら、誰も新しいものなんか作らないわけです。
新しいOSも新しいパソコンも新しいソフトも出ない世界は、それは
もう楽しくないと思います。
新しいものが出れば、それに対応した新しい機能が必要で、逆に
対応してない古いもので対応する方が、精力を取られるようになって
きますけどね。。。

まぁ、VB6とVBAは同期が取れてて優秀ですし、VBに限らずスクリプトは
お手軽ですので知って損なモノでは無いです。ただ、質問者さんはVB6を
それなりに知ってるようですが、VBSはどうか分からないですよね。
そしたら、結局同じことなんですよ。自分の知っていることで完結
できるならそれは楽ですけど、新しいものはどんどん生まれていって
ますし、古いものでもじゃあ全部知っているのか?となったら知らなかった
機能に日々出会うわけですよ。どんな目的であっても無視できないと
思いますけどね。

>For Me.i = 1 To 20 
>  DirectCast(Me.Controls.Item("PictureBox" & i), PictureBox).Image = ABC.Image
>Next
まぁ、別に何でもいいんだけど、この方法は毎回コントロールを検索しないと
いけないから、プログラムの効率としては少し評価が下がります。
(パソコンの性能が良すぎるので普通に使ってる分には問題になりませんが)
コントロールの配列を作る方法は、VB6でも同じコード書けるし分かり易いですし、
検索せずにコントロールにアクセスできるから、実は優秀だったりします。

>いまいち、わからない部分もあるのですが、少しずつ歩いていきます。
VB6でも以下のコードは有効なのです。。。
DirectCast はヘルプの解説そのままですし。。。
    Dim cControl As Control
    Set cControl = Me.Controls("Picture1")


。。。DotNetになってもあんま変わってない話題なんですが。
投稿者 流れ者  (その他) 投稿日時 2009/12/25 01:26:23
こんにちは。

現実問題、かも健。。壱さんのサンプルが回答の中では理想に近いですね。
(コメントはかなり挑発的ですが。。。 ^^;))

   Dim my_pictureBox_kazu As Integer = 10
    Dim my_pictureBox(my_pictureBox_kazu - 1) As PictureBox
    Private Sub Form1_Load(ByVal sender As ObjectByVal e As System.EventArgs) Handles Me.Load
        my_pictureBox(0) = PictureBox1
        my_pictureBox(1) = PictureBox2
        my_pictureBox(2) = PictureBox3
        my_pictureBox(3) = PictureBox4
        my_pictureBox(4) = PictureBox5
        my_pictureBox(5) = PictureBox6
        my_pictureBox(6) = PictureBox7
        my_pictureBox(7) = PictureBox8
        my_pictureBox(8) = PictureBox9
        my_pictureBox(9) = PictureBox10
        For i As Integer = 0 To my_pictureBox_kazu - 1
            my_pictureBox(i).BackColor = Color.Blue
            my_pictureBox(i).Size = New Size(10, 10)
            my_pictureBox(i).Location = New Point(30 + i * 20, 30)
            AddHandler my_pictureBox(i).Click, AddressOf my_pictureBox_click
        Next
    End Sub




   Const my_pictureBox_kazu As Integer = 10
    Dim my_pictureBox(my_pictureBox_kazu - 1) As PictureBox
    Private Sub Form1_Load(ByVal sender As ObjectByVal e As System.EventArgs) Handles Me.Load

        For i As Integer = 0 To my_pictureBox_kazu - 1
       Set my_pictureBox(i) = Me.Controls("PictureBox" & i)
            my_pictureBox(i).BackColor = Color.Blue
            my_pictureBox(i).Size = New Size(10, 10)
            my_pictureBox(i).Location = New Point(30 + i * 20, 30)
            AddHandler my_pictureBox(i).Click, AddressOf my_pictureBox_click
        Next
    End Sub


と修正すれば、シンプルになりますね。
投稿者 るしぇ  (社会人) 投稿日時 2009/12/25 01:55:05
>現実問題、かも健。。壱さんのサンプルが回答の中では理想に近いですね。
リンク先に同じようなコード紹介済みなんだけど、何と比較して理想なのよ。
>と修正すれば、シンプルになりますね。
シンプルにしない所に意味があるコードなのです。
デザイン画面重視なら、コードでサイズや位置指定するのも蛇足です。
        my_pictureBox(0) = PictureBoxTopLeft
        my_pictureBox(1) = PictureBoxTopCenter
        my_pictureBox(2) = PictureBoxTopRight
        my_pictureBox(3) = PictureBoxMiddleLeft
        my_pictureBox(4) = PictureBoxMiddleCenter
        my_pictureBox(5) = PictureBoxMiddleRight
        my_pictureBox(6) = PictureBoxBottomLeft
        my_pictureBox(7) = PictureBoxBottomCenter
        my_pictureBox(8) = PictureBoxBottomRight
投稿者 流れ者  (その他) 投稿日時 2009/12/27 20:09:03
こんにちは。

>リンク先に同じようなコード紹介済みなんだけど、何と比較して理想なのよ。
リンク先は見ていません。あくまで、このスレッドの中だけを見て、判断しました。
軽率な発言をいたしまして、申し訳ござません。

>シンプルにしない所に意味があるコードなのです。
わたしは、かも健。。壱さんのサンプルのコントロール名が、「”PictureBox”+ 連番」であったことから、それなら、シンプルに出来ると判断し、提示しました。コントロール名に規則性が無い場合、
かも健。。壱さんのサンプルが適当であることは承知しています。

どうやら、わたしは、見当違いの回答をしていたようです。重ねてお詫びいたします。
投稿者 るしぇ  (社会人) 投稿日時 2009/12/27 23:28:15
>どうやら、わたしは、見当違いの回答をしていたようです。重ねてお詫びいたします。
いえ、相手の実力を全く見ず、管理人さんのハンドルを使って
内容スカスカの書込みをする人と同じ内容の書込みを「理想」
と言われたので、いらっときただけです。
投稿者 (削除されました)  () 投稿日時 2009/12/28 03:45:51
(削除されました)