出産前後の痔にはご注意!

教えてください。
実行中にコントロールを生成したいのですが、

Public Class Form1
 Private myTxt(,) As System.Windows.Forms.TextBox

 Me.myTxt = New System.Windows.Forms.TextBox(59, 2) {}
 Dim i As Integer
 Dim j As Integer
 Dim h As Integer
 Dim p As Integer

 h = 10
 p = 100
 For i = 0 To Me.myTxt.GetLength(0) - 1
  For j = 0 To Me.myTxt.GetLength(1) - 1
   Me.myTxt(i, j) = New System.Windows.Forms.TextBox
   Me.myTxt(i, j).Name = "myTxt" + i.ToString() + j.ToString()
   Me.myTxt(i, j).Size = New Size(100, 30)
   Me.myTxt(i, j).Location = New Point(p, h)
   p = p + 100
  Next j
  h = h + 30
 Next i

 Me.myPnl.Controls.AddRange(Me.myTxt)

と書くと最後の行が波線になり、
“型 'System.Windows.Forms.TextBox の 2 次元配列' の値を
'System.Windows.Forms.Control' に変換できません。”とエラーになります。

これはAddRangeは多次元配列に使用できないということなのでしょうか?
色々検索してみましたが、コントロールの生成に関する多次元配列が見つけられずに
困っていました。

最後のAddRange(Me.myTxt)をAdd(Me.myTxt(i,j))などと変えたりしても別のエラーになり、
基本的に間違っている気がしますがどこだかがわかりません。

詳しい方、宜しくお願い致します。

このQ&Aに関連する最新のQ&A

A 回答 (1件)

Control.ControlCollection.AddRangeはControlの一次元配列を引数にとります。


ref) http://msdn.microsoft.com/ja-jp/library/system.w …

このため,二次元配列を直接引数に渡すことはできません。
一次元配列にすれば良いのですが,配列はIEnumerable(Of T)を一次元配列の時のみ実装するため,
myTxt.Cast(Of Control).ToArray()
のようにIEnumerable(Of Control)を経由して一次元配列にすればよいでしょう。
# IE(Of T)を二次元配列も実装してくれればToArray()一発だったのですが……。
    • good
    • 0
この回答へのお礼

なるほどIEnumerableインターフェイスを実装して、一次元配列としてまとめる必要があるわけですね。
その方法で試してみます。ありがとうございました。

お礼日時:2012/12/18 15:13

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QVBのコントロール配列を二次元配列にする方法

タイトル通りです。
テキストボックスなどをコントロール配列で持つときに二次元配列で持つ方法はないでしょうか?

ご回答の方、宜しくお願いします。

Aベストアンサー

コントロールのIndexプロパティを利用する方法では二次元配列はできません。
しかし、変数としての二次元配列ならできます。

Dim TextBoxes(3, 10) As TextBox

などとすると、テキストボックスの多次元配列ができます。
ただし、この変数にはインスタンスがないので、インスタンスは別に作成してやる必要があります。

以下に例を示します。

名前がTexts、Indexが0のTextBoxを配置します。
フォームモジュールに以下を貼り付けます。

Option Explicit

Private TextBoxes(3, 10) As TextBox

Private Sub Form_Load()

On Error Resume Next
Dim N As Long, M As Long, T As Long

For N = 0 To 2

For M = 0 To 9

T = N * 10 + M
Load Texts(T) 'Load Texts(0)はエラーだが無視される
Set TextBoxes(N, M) = Texts(T)
TextBoxes(N, M).Left = N * 1320
TextBoxes(N, M).Top = M * 300
TextBoxes(N, M).Visible = True

Next M

Next N

End Sub

Private Sub Texts_Click(Index As Integer)

MsgBox "これは(" & (Index \ 10) & ", " & (Index Mod 10) & ")です"

End Sub

この方法を使う場合、TextBoxes(N, M)のIndexプロパティはN * 10 + Mを示すので、注意が必要です。

コントロールのIndexプロパティを利用する方法では二次元配列はできません。
しかし、変数としての二次元配列ならできます。

Dim TextBoxes(3, 10) As TextBox

などとすると、テキストボックスの多次元配列ができます。
ただし、この変数にはインスタンスがないので、インスタンスは別に作成してやる必要があります。

以下に例を示します。

名前がTexts、Indexが0のTextBoxを配置します。
フォームモジュールに以下を貼り付けます。

Option Explicit

Private TextBoxes(3, 10) As TextBox

...続きを読む

QVB.NETで他のプロジェクトで作成したフォームを使う方法

こんにちは。
VB.NETのプロジェクトがぐちゃぐちゃで参照設定とかいろんなの呼んでしまっているので、新しく作成しなおしたいのですが、
新しいプロジェクトでプロジェクトを作成し、前のプロジェクトで必要なファイル(.vb、RESX)を新しいプロジェクトのフォルダにコピーしたのですが、
普通のモジュールは追加>新しい項目の追加でなんとか追加できたのですが、フォームの追加の仕方がわかりません><教えてくださいー

P.S. RESXファイルってフォームのデータが入ってるのでしょうか?そんな気がしてコピーしたのですが。

※VB6.0からVB.NETに以降した際にアップデート情報みたいなのがプログラム上にくっついてしまって.vbファイルも参照項目も増えまくってしまった

Aベストアンサー

ドラッグ&ドロップが使いやすい。
Windowsのエクスプローラでvbファイルをドラッグして、VS.NETのソリューションエクスプローラへドロップする。

Qvb.netで画面のコントロールId名を変数で動的に制御し処理する方法

以下のような処理がしたいです。
実現方法をご存知でしたらご教授下さい。

画面のコントロールText1~Text3があります。
For~Nextでこのコントロールに値をセットしたいです。

For i = 1 To 3
  Texti.Text = i
  ※このiのTextの後ろのiの部分を1~3と動的に変更し、各Textに値を設定したいです。
Next

Aベストアンサー

こんにちは、webでは、findcontrolを使うみたいです。

いかに、参考URLから、引用すると
***********************************
Dim L, U, i As Integer
Dim tx As System.Web.UI.WebControls.TextBox
L = LBound(dat)
U = UBound(dat)
For i = L To U
'コントロール名を探し出す
tx = FindControl("TextBox" & CStr(i))
'見つかったコントロールのTextプロパティに代入
tx.Text = dat(i)
Next

******************引用終わり*******
このようにすると良いみたいです。
asp findcontrolで、検索すると、
結構ヒットするみたいです。

参考URL:http://natchan-develop.seesaa.net/

Qコントロール配列と同じような扱い方

TextBox1、TextBox2、TextBox3・・・・TextBox10 と10個のテキストボックスにVB6で使っていたコントロール配列と同じような処理の仕方をコードで教えていただけませんか。

for i=0 to 9
TextBox(i).Text=i
next i

上記のコードをVB.NETで書くとすれば、どのように書けばいいかということさえわかれば、なんとか頑張れる気がします。

Aベストアンサー

VB.NETに「コントロール配列」は無いので、基本的にはできません。

やるとしたら、
「VB6で普通の(コントロール配列でない)コントロールを『コントロール配列』と同じように扱う」
場合と同じです。

つまり・・・
(方法1)自分でコントトール型の配列を宣言し、各コントロールをセットしておく。
(方法2)Controlsコレクションから参照する。
のどちらかでしょう。

前者なら例えば、
-------------------------------------------------------
Private TextBoxArray() As TextBox
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
TextBoxArray = New TextBox() {Me.TextBox1, Me.TextBox2, Me.TextBox3}
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim i As Integer
For i = 0 To 2
TextBoxArray(i).Text = i.ToString
Next
End Sub
-------------------------------------------------------
こんな感じ、後者なら、
-------------------------------------------------------
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim i As Integer
For i = 1 To 3
Me.Controls("TextBox" & i.ToString).Text = i.ToString
Next
End Sub
-------------------------------------------------------
こんな感じ。

VB.NETに「コントロール配列」は無いので、基本的にはできません。

やるとしたら、
「VB6で普通の(コントロール配列でない)コントロールを『コントロール配列』と同じように扱う」
場合と同じです。

つまり・・・
(方法1)自分でコントトール型の配列を宣言し、各コントロールをセットしておく。
(方法2)Controlsコレクションから参照する。
のどちらかでしょう。

前者なら例えば、
-------------------------------------------------------
Private TextBoxArray() As TextBox
...続きを読む

Q他のフォームから別のフォームのサブルーチンを呼び出す

例えばフォームAからフォームBのCommand1_clickというサブルーチンを呼び出そうとすればどのようにすればいいんでしょうか?

私は

Call FormB!Command_click

とフォームAに書きましたがうまくいきませんでした

Aベストアンサー

Command1のClickイベントプロシージャの

Private Sub Command1_Click()
'(・・処理・・)
End sub



Public Sub Command1_Click()
'(・・処理・・)
End sub

に書き換えて下さい(「Private」→「Public」)。
こうすることにより、他のフォームから呼ぶことが可能になります。
ただしこのやり方は奨励しません(※後述)

また、呼び出し方も間違ってます。

Call FormB!Command_click

ではなく、

Call FormB.Command_click

として下さい(「!」→「.」)。

※自動生成するイベントプロシージャの構文を直接いじるのはあまり奨励しません(特に問題は発生しませんが)。
直接イベントプロシージャを呼ぶのではなく、下記のようにしてみてはいかがでしょう。

※下記をFormBに記述

Private Sub Command1_Click()
Call subCommand1Click
End sub

Public Sub subCommand1Click()
'(・・処理・・)
End sub

FormAではこのように呼ぶ
Call FormB.subCommand1Click

Command1のClickイベントプロシージャの

Private Sub Command1_Click()
'(・・処理・・)
End sub



Public Sub Command1_Click()
'(・・処理・・)
End sub

に書き換えて下さい(「Private」→「Public」)。
こうすることにより、他のフォームから呼ぶことが可能になります。
ただしこのやり方は奨励しません(※後述)

また、呼び出し方も間違ってます。

Call FormB!Command_click

ではなく、

Call FormB.Command_click

として下さい(「!」→「.」)。

※自動生成...続きを読む

QC#で構造体の配列を持った構造体を使いたいのですが

C#で構造体の配列を持った構造体を使いたいのですが
Cならば
struct xyz {
struct abc _abc[32];
int index;
};
struct abc {
int a;
int b;
int c;
};

struct xyz _xyz[8];
xyz[0]._abc[3].b = 1;

のような使い方で という感じで やっていた事を C#で 同じような事をやろうとしても うまくいきません
うまくやる方法をどなたかご存知ないでしょうか

Visual Studio 2005行った場合
コンパイルで
構文エラーです。不適切な配列の宣言子です。マネージ配列を宣言するには、次元指定子を変数の識別子の前に指定します。固定サイズ バッファ フィールドを宣言するには、フィールド型の前に fixed キーワードを使用します
となり

fixed をつけると

固定サイズ バッファの型は次のうちの 1 つでなければなりません: bool、byte、short、int、long、char、sbyte、ushort、uint、ulong、float または double

となってしまいます

C#で構造体の配列を持った構造体を使いたいのですが
Cならば
struct xyz {
struct abc _abc[32];
int index;
};
struct abc {
int a;
int b;
int c;
};

struct xyz _xyz[8];
xyz[0]._abc[3].b = 1;

のような使い方で という感じで やっていた事を C#で 同じような事をやろうとしても うまくいきません
うまくやる方法をどなたかご存知ないでしょうか

Visual Studio 2005行った場合
コンパイルで
構文エラーです。不適切な配列の宣言子です。マネージ配列を宣言するに...続きを読む

Aベストアンサー

C# では、配列は「単なる連続したメモリ領域」ではなくて「添字によってオブジェクトを格納できるオブジェクト」であることに注意しなくてはいけません。つまり、C では配列は一種の構造体でしたが、C# では配列は参照型のオブジェクトです。
よって、C のように予めサイズを固定しておくということは基本的にできません。配列の大きさは配列のインスタンスが作られるときに動的に決まります。

C# では、参照型のオブジェクトを構造体のメンバにすることはあまりありません。null 値の扱いが面倒だからです。
また、C# では構造体の大きさは大きくとも 20 バイト程度までにします。C# では基本的に「構造体へのポインタ」はありません。巨大な構造体をそのまま扱うのはメモリの使い方の観点からいって非効率的です。

今回の件では、構造体ではなくクラスにするのがよいかと思われます。

QCloseとDisposeの違い

みなさまこんばんわです。よろしくお願い申し上げます。

VB.NET 2008でコーディングしています。
CloseとDisposeの違いについて教えていただきたいのです。

これらのメソッドは、開いたファイルを閉じるときなどにも使いますが、今回お尋ねするのは、フォームを閉じるとき、しかも、自ら呼び出すとき(Me.Close() と、Me.Dispose() )のみに限ったこととしてお話しさせていただきます。

たとえば、ShowDialog() で呼び出したフォームは、そのフォーム内でMe.Close() しても、プロセスは残り、たとえば、タイマーコントロールのイベントに記述していますと、それは実行され続けます。

これを防ぐために、Me.Dispose() を使います。すると、きれいにプロセスは終了し、イベントは発生しない模様です。

そこで、「フォームを閉じる」意味のMe.Close() をすべてMe.Dispose() に変えてしまいました。確実にプロセスを破棄出来ると思ったからです。Webで調べると、違いは「再利用できる、できないの違い」という答えがありましたが、それはきっと、ファイルやオブジェクトのことで、フォームの場合は、再びShowまたはShowDialogで表示させることは可能でしたので、特に問題は感じていませんでした。

ところが、アプリケーション設定で、「最後のフォームを閉じるとき」にアプリケーションがシャットダウンする設定になってるのに、シャットダウンしてくれないことが起こりました。調べてみると、Me.Dispose() が原因。Me.Close() に変えるとうまくいきました。

わけわからなくなってきました。。。

ちなみに、その残ったフォームは、スタートアップフォームであり、別のフォームからShowまたはShowDialogメソッドで呼び出したものではありません。

ここで4つの仮説を立ててみました。

1. ShowDialogで呼び出したフォームは、Me.Dispose()、Showで呼び出した、あるいは、スタートアップフォームは、Me.Close() すれば破棄できる

2. ShowDialogで呼び出したフォームは、Me.Dispose()、スタートアップフォームは、Me.Close()、Showで呼び出したフォームは、どちらでも、破棄できる

3. 呼び出し方ではなく、別の要因が存在する

4. 併記する必要がある場合がある

Me.Close()
Me.Dispose()

または、

Me.Dispose()
Me.Close()



どれが正しいのでしょうか?どなたがご存じの方がいらっしゃいましたら、ご教授いただけませんでしょうか? どうぞよろしくお願い申し上げます。ありがとうございました。

みなさまこんばんわです。よろしくお願い申し上げます。

VB.NET 2008でコーディングしています。
CloseとDisposeの違いについて教えていただきたいのです。

これらのメソッドは、開いたファイルを閉じるときなどにも使いますが、今回お尋ねするのは、フォームを閉じるとき、しかも、自ら呼び出すとき(Me.Close() と、Me.Dispose() )のみに限ったこととしてお話しさせていただきます。

たとえば、ShowDialog() で呼び出したフォームは、そのフォーム内でMe.Close() しても、プロセスは残り、たとえば、...続きを読む

Aベストアンサー

Me.Close()
Me.Dispose()
は根本的に違うものです。

formについて、Close()メソッドはフォームの表示を終了させるメソッドです。

ほかのクラスも同様。すべてのDispose()メソッドについて、これはインスタンスの破棄を明示的に行うものです。

>再利用できる、できないの違い

Dispose()はインスタンスが破棄されるため、再びコンストラクタを用いて、インスタンスを生成しないいけません。

一方Close()はインスタンスが残っているので、それを利用することができます。

>1. ところが、アプリケーション設定で、「最後のフォームを閉じるとき」にアプリケーションがシャットダウンする設定になってるのに、シャットダウンしてくれないことが起こりました。調べてみると、Me.Dispose() が原因。
Me.Close() に変えるとうまくいきました。

通常はどちらでもうまくいきます。

>2. ShowDialogで呼び出したフォームは、Me.Dispose()、スタートアップフォームは、Me.Close()、Showで呼び出したフォームは、どちらでも、破棄できる

ShowDialogの場合は、メソッド内部で、ハンドルが破棄されているため、Close()メソッドの際にDispose()メソッドが呼び出されます。

>3. 呼び出し方ではなく、別の要因が存在する

そう思います。

>4. 併記する必要がある場合がある

インスタンスを明示的に破棄したほうがよい場合は多く存在します。
Disposeが使えるメンバはIDisposableをインターフェースとして持っているメンバです。
これらのメンバは、外部とのやり取りを行うものが多くあります。
たとえばSQLClientに含まれるようなメンバです。

外部とのコネクションを確実に破棄を保障してほしいなどという場合がありますよね、このようなときに使用します。

Using構文を使用するのとまったく同じ理由になります。
正確にはUsing構文を使用できるメンバには条件があります、IDisposableをインターフェースとして持っているメンバに限るというものです。

ほかにもガーベージコレクタによるファイナライズを伴うかどうかという違いがあります。
Disposeの場合はファイナライズが同時に行われるため、使用していたメモリ空間を開放することができます。

上記のような理由により、
Me.Close()
Me.Dispose()
は両方書いたほうがよいと思います。

蛇足ですが、
Me.Dispose()
Me.Close()
はエラーになります。
Me.Dispose()により、Me本体(インスタンス)は削除されてしまいます。
存在しないMeに対してCloseメソッドを要求することはできないためです。

Me.Close()
Me.Dispose()
は根本的に違うものです。

formについて、Close()メソッドはフォームの表示を終了させるメソッドです。

ほかのクラスも同様。すべてのDispose()メソッドについて、これはインスタンスの破棄を明示的に行うものです。

>再利用できる、できないの違い

Dispose()はインスタンスが破棄されるため、再びコンストラクタを用いて、インスタンスを生成しないいけません。

一方Close()はインスタンスが残っているので、それを利用することができます。

>1. ところが、アプリ...続きを読む

QVB6.0でテキストボックスの書式設定をしたいのですが、

VB6.0でテキストボックスの書式設定をしたいのですが、
以下のコードを入れてみたところ.Formatの部分で、
エラー(メソッドまたはメンバーが見つかりません)がでます。
どう書き直したらよろしいでしょうか?
教えてください。よろしくお願いします。

数値を小数点2桁まで表示したいです。

Private Sub Text_Change(Index As Integer)
For i = 6 To 16
Me.Text(i).Format = "0.00"
Next i
End Sub

Aベストアンサー

VB6でのFormat関数の使い方が違うのでは。たとえば、

Format(Form1.Text1.Text, "#0,00")

以下の、

http://msdn.microsoft.com/ja-jp/library/59bz1f0h%28VS.80%29.aspx

の下部を参照。

Q2次元動的配列の第一引数のみを可変にする

ReDim Preserve aStrSKU(x, 2)
aStrSKU(x, 0) = strPre
aStrSKU(x, 1) = サブ2
aStrSKU(x, 2) = サブ3

x = x + 1

上記のソースをDo Untilでまわしているのですが、
2週目以降にxに1を足して行数だけ増やしたいのですが、
2週目でエラーが発生します。
行数だけ要素数を増やす方法はありますか?

Aベストアンサー

こんな感じで

Structure column
Dim col1 As String
Dim col2 As String
Dim col3 As String
End Structure

Private Sub test()

Dim aStrSKU() As column
Dim x As Integer

Do Until x = 3
ReDim Preserve aStrSKU(x)
aStrSKU(x).col1 = "strPre"
aStrSKU(x).col2 = "サブ2"
aStrSKU(x).col3 = "サブ3"

x = x + 1
Loop

End Sub

Q一時停止と再開

今、Visual Basic でスライドショーのプログラムを作っています。
その中で、プログラムの一時停止(それに伴う再開)という事をしたいのですが、どのようにすればよいかわかりません。
教えて下さい。お願いします。

Aベストアンサー

Enabledの操作で充分だと思いますよ。

ちなみに先ほどの方法の処理を書くと(フラグの1と0の値が変わってますが・・・)

Private bytFlg As Byte

Private Sub cmdPause_Click()
  bytFlg = 0
End Sub

Private Sub cmdPlay_Click()
  bytFlg = 1
End Sub

Private Sub Form_Load()
  bytFlg = 0
End Sub

Private Sub Timer1_Timer()
  If bytFlg = 1 Then
    'ここに画像読み込み処理
  End If
End Sub

とするとできます。
しかし、画像の読み込みを必要としないときもタイマーが動いているので、Windowsに負荷がかかります。

だからgotkatさんの今までのEnabledの操作で充分です


人気Q&Aランキング