tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルTabControlをTabStripのように使いたい
記事No6112
投稿日: 2007/08/21(Tue) 14:35
投稿者皐月
こんにちは、いつもお世話になっています。VB2005について質問です。

VB6でTabStripに配列にしたテキストボックスを貼り付けたものに順に取り込んだ値を入れるような処理をしていました。TabStripのタブは「0-9」「10-19」と取り込んだ順番の値を分けるために利用していました。各タブに表示されるテキストボックスはまったく同じでタブのインデックスで中に挿入するデータを判断し挿入していました。

これと同じ動作をVB2005のTabControlとDataGridViewを利用して実現しようと思ったのですが、TabControlの場合タブごとに新しくDataGridViewを作成しなければいけないので面倒な上、ソースも以前と比べスマートさがなくなってしまいました。DataGridViewのコントロールがTabStripと同じように1つで作成できるなら、もっとスマートな作りにできると思うのですが、TabControlはTabStripと同じ用に使用することはできないのでしょうか?

[ツリー表示へ]
タイトルRe: TabControlをTabStripのように使いたい
記事No6125
投稿日: 2007/08/22(Wed) 20:45
投稿者るしぇ
対象の DataGridView をタブを切り替えるたびに移動させればいいのでは?
[Control.Controls プロパティ]
http://msdn2.microsoft.com/ja-jp/library/system.windows.forms.control.controls(VS.80).aspx

[ツリー表示へ]
タイトルRe^2: TabControlをTabStripのように使いたい
記事No6183
投稿日: 2007/08/28(Tue) 16:43
投稿者皐月
お返事ありがとうございます。msdnのページを確認して例題をしたところ、ラジオボタンの追加と削除ができるようになりこれを応用して、

Private Sub TabControl1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles TabControl1.SelectedIndexChanged

の条件でDataGridViewをタブページに移動をさせたかったのですが、移動させるという動作がわからず、詰まってしまいました。移動の動作はaddやRemoveを使って作成するのでしょうか?

[ツリー表示へ]
タイトルRe^3: TabControlをTabStripのように使いたい
記事No6184
投稿日: 2007/08/28(Tue) 18:25
投稿者るしぇ
どうすればいいのか?少しでも予想が付いているのであれば、自分で調べて、
テストして、確認するべきでは?

その上で、問題点がある場合や、理解できなかった部分があるなら、具体的に
問題点のみを、相手に伝わる形で質問願います。

[ツリー表示へ]
タイトルRe^4: TabControlをTabStripのように使いたい
記事No6185
投稿日: 2007/08/29(Wed) 09:58
投稿者ダンボ
>DataGridViewをタブページに移動をさせたかったのですが、
>移動させるという動作がわからず、詰まってしまいました。
>移動の動作はaddやRemoveを使って作成するのでしょうか?

るしぇ さんの愛の指導も良く分かります。もう少しヒントを上げましょう。
・この場合の「移動」は「addやRemove」を使うことではない
・「コンテナ」という言葉をまず検索して調べるべき
・「コンテナになれるコントロール」「コンテナになれないコントロール」がある
・子供は親を選べる

[ツリー表示へ]
タイトルRe^5: TabControlをTabStripのように使いたい
記事No6190
投稿日: 2007/08/29(Wed) 16:12
投稿者るしぇ
> ・この場合の「移動」は「addやRemove」を使うことではない
> ・「コンテナ」という言葉をまず検索して調べるべき
> ・「コンテナになれるコントロール」「コンテナになれないコントロール」がある
> ・子供は親を選べる
ん?コントロールは[VB2005]のものを使ってるんだよね?
[VB6.0]のときは Container プロパティがあったけど、.NET以後だと
Controls プロパティのコレクションに追加するのでは?

コレクションへの追加削除のみの話で、オブジェクトのインスタンスは別で生成
するだろうから、addやRemove しても問題ないと思ってた。だから、テストして
くださいとしか書かなかったんですが。

ま、その辺も含めて、調べてくれた結果を報告してくれればいい話だけど。

[ツリー表示へ]
タイトルRe^6: TabControlをTabStripのように使いたい
記事No6207
投稿日: 2007/08/30(Thu) 15:51
投稿者ダンボ
> ん?コントロールは[VB2005]のものを使ってるんだよね?
> [VB6.0]のときは Container プロパティがあったけど、.NET以後だと
> Controls プロパティのコレクションに追加するのでは?

はい、私の早とちりです。確認せずに投稿してすみません。
どうしてこんな便利なContainerプロパティを無くすんでしょう?

(皐月 さん、回答者どうしで話してすみません)

[ツリー表示へ]
タイトルRe^7: TabControlをTabStripのように使いたい
記事No6212
投稿日: 2007/08/31(Fri) 11:04
投稿者魔界の仮面弁士
>> 皐月さん (No.6112)
> TabControlはTabStripと同じ用に使用することはできないのでしょうか?

できますよ。
そういうときには、子コントロールを TabPage の上に配置するのではなく、
フォームに直接配置すれば良いかと思います。


まずはデザイン時に、DataGridView をフォームに直接貼り付けてください。
その DataGridView を選択後、右クリックして[最前面へ移動]を選択してから、
DataGridView を TabControl に重なる位置まで移動させれば OK。
移動には矢印キーを使うか、DataGridView の Location プロパティを手動設定で。



>> るしぇさん (No.6190)
> [VB6.0]のときは Container プロパティがあったけど、.NET以後だと
> Controls プロパティのコレクションに追加するのでは?

その方法でもできますが、親コントロールを変更する目的であれば、
Parent プロパティを設定する方がわかりやすいかも知れません。
(VB6 の Container プロパティの処理イメージにも近いですしね)



>> ダンボさん (No.6207)
> どうしてこんな便利なContainerプロパティを無くすんでしょう?

.NET にも Containerプロパティ自体は存在しますが、VB6 とは意味が変わっていますね。
VB6 の Container は、親コントロール(コンテナ コントロール)を指すプロパティですが、
.NET の Container は、(コントロールではなく)コンポーネントを管理するものです。
(コンポーネントの例としては、System.Windows.Forms.Timer などがあります)


そもそも .NET では、コントロールの親子関係をわかりやすくするため、VB6 とは
コントロールの管理方法が変化しています。たとえば、以下の 2 つの構成を比べてみましょう。

<VB6>                 <.NET>
 Form1                  Form1
 ├Frame1               ├GroupBox1
 │├Frame2             │├GroupBox2
 ││└Command1         ││└Button1
 │└Command2           │└Button2
 └Command3             └Button3


<VB6>
 Me.Controls        … すべてのコントロールを示す。(Frame1, Frame2, Command1, Command2, Command3)
 
 Frame1.Parent      … Form1 を示す。
 Frame2.Parent      … Form1 を示す。
 Command1.Parent    … Form1 を示す。
 Command2.Parent    … Form1 を示す。
 Command3.Parent    … Form1 を示す。
 
 Frame1.Container   … Form1  を示す。
 Frame2.Container   … Frame1 を示す。
 Command1.Container … Frame2 を示す。
 Command2.Container … Frame1 を示す。
 Command3.Container … Form1  を示す。


<.NET>
 Me.Controls        … フォーム直下のコントロールを示す。(GroupBox1, Button3)
 GroupBox1.Controls … GroupBox1直下のコントロールを示す。(GroupBox2, Button2)
 GroupBox2.Controls … GroupBox2直下のコントロールを示す。(Button1)
 
 GroupBox1.Parent   … Form1     を示す。
 GroupBox2.Parent   … GroupBox1 を示す。
 Button1.Parent     … GroupBox2 を示す。
 Button2.Parent     … GroupBox1 を示す。
 Button3.Parent     … Form1     を示す。


VB6 の場合、「○○の親コントロール」は得やすいですが(Container プロパティ)、
「××の子コントロール」を得る方法が用意されていませんでした。

一方.NET の場合、親は Parent プロパティ、子は Controls プロパティで管理され、
コントロールの階層構造を容易に把握できるようになっていますね。



ちなみに .NET では、Form も Control の一種となったため、こんなことも可能です。

Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
    Dim F As New Form()
    F.Text = "サンプル"
    F.TopLevel = False
    Me.Controls.Add(F)   'Me ではなく、Button1 や RichTextBox1 の上にも配置可能。
    F.Visible = True
End Sub

[ツリー表示へ]
タイトルRe^8: TabControlをTabStripのように使いたい
記事No6220
投稿日: 2007/09/03(Mon) 18:03
投稿者皐月
るしぇさん、ダンボさん、魔界の仮面弁士さんお返事ありがとうございます。
自分で中途半端に調べたままで再度質問をしてしまい、失礼しました。
あのような質問の仕方ではコメントを下さる方もわかりにくかったと思います。

> >> 皐月さん (No.6112)
> > TabControlはTabStripと同じ用に使用することはできないのでしょうか?
>
> できますよ。
> そういうときには、子コントロールを TabPage の上に配置するのではなく、
> フォームに直接配置すれば良いかと思います。
>
>
> まずはデザイン時に、DataGridView をフォームに直接貼り付けてください。
> その DataGridView を選択後、右クリックして[最前面へ移動]を選択してから、
> DataGridView を TabControl に重なる位置まで移動させれば OK。
> 移動には矢印キーを使うか、DataGridView の Location プロパティを手動設定で。

魔界の仮面弁士さん、丁寧なお返事ありがとうございます。こちらの方法を新しくプロジェクトを立てて試してみたのですが、TabControlの子コントロールになってしまい上手くいきませんでした。
なので、

>Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles >Button1.Click
>    Dim F As New Form()
>    F.Text = "サンプル"
>    F.TopLevel = False
>    Me.Controls.Add(F)   'Me ではなく、Button1 や RichTextBox1 の上にも配置可能。
>    F.Visible = True
>End Sub

のサンプルコードとるしぇさんの意見を参考にして

Private Sub TabControl1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles TabControl1.Click
        TabPage1.Controls.Add(DataHeadGrid1)
        TabPage2.Controls.Add(DataHeadGrid1)
        TabPage3.Controls.Add(DataHeadGrid1)
        Call aa()
    End Sub

としてみました。このコードではTabPage3にのみDataHeadGrid1がaddされほかのTabPageにはaddされませんでした。そこで、もう一度質問させて頂きたいのですが、TabControl1_Clickで呼び出されたTabPageを特定して入れる処理をしたいと思います。最初プロパティTabPagesの中のTagと言うプロパティに値を設定して、それでクリックされたTabPageを判断しようと考えたのですが、上手くいきませんでした。
ご教授お願い致します。

[ツリー表示へ]
タイトルRe: TabControlをTabStripのように使いたい
記事No6222
投稿日: 2007/09/03(Mon) 18:46
投稿者魔界の仮面弁士
> こちらの方法を新しくプロジェクトを立てて試してみたのですが、
> TabControlの子コントロールになってしまい上手くいきませんでした。

う〜む。当方では、これで実現できているのですけれどね。
デザイン時の設定だけですむので、追加コードも一切不要のはず。

もう一度確認したいのですが、どこかで手順を間違っていませんか?
最初に「フォームに貼り付ける」ところで、誤って「TabPage に貼り付け」ていた、とか。


> TabControlの子コントロールになってしまい上手くいきませんでした。

……そもそも、TabControl の子コントロールになれるのは、TabPage だけのはずです。
DataGridView を、無理に TabControl (≠TabPage) の子コントロールにしようとしても、
ArgumentException のエラーが発生してしまうはずなので、何かがおかしいです。

何か特殊な処理をおこなっていますか?



>  TabPage1.Controls.Add(DataHeadGrid1)
>  TabPage2.Controls.Add(DataHeadGrid1)
>  TabPage3.Controls.Add(DataHeadGrid1)
> としてみました。

同時に複数の親を持つことはできません。
別の親コントロールに Controls.Add すると、その子コントロールは
前の親から離縁して、新しい親に引き取られていく事になります。

そのため、
> このコードではTabPage3にのみDataHeadGrid1がaddされ
であるかのように見えてしまっている、ということです。


> TabControl1_Clickで呼び出されたTabPageを特定して入れる処理をしたいと思います。
どちらかというと、SelectedIndexChanged あたりの方が良いような気も。

[ツリー表示へ]
タイトルRe^2: TabControlをTabStripのように使いたい
記事No6228
投稿日: 2007/09/04(Tue) 10:05
投稿者皐月
魔界の仮面弁士さん、お返事ありがとうございます。

> もう一度確認したいのですが、どこかで手順を間違っていませんか?
> 最初に「フォームに貼り付ける」ところで、誤って「TabPage に貼り付け」ていた、とか。

魔界の仮面弁士さんの言うように「フォームに貼り付ける」ところで、誤って「TabPage に貼り付け」てしまっていたようです。Locationのプロパティで調節したところ上手くいきました。


> > TabControlの子コントロールになってしまい上手くいきませんでした。
>
> ……そもそも、TabControl の子コントロールになれるのは、TabPage だけのはずです。
> DataGridView を、無理に TabControl (≠TabPage) の子コントロールにしようとしても、
> ArgumentException のエラーが発生してしまうはずなので、何かがおかしいです。
>
> 何か特殊な処理をおこなっていますか?

DataGridViewをGroupBoxの中のラジオボタン(子コントロール)のように捉えていました。失礼しました。DataGridViewはTabPageに貼り付けという形がとれるようなので、その場合はTabPageの子コントロールということになるのでしょうか?

 Form1
 └TabControl
   └TabPage
           └DataGridView

今は上記のようなイメージをもっています。

[ツリー表示へ]
タイトルRe^3: TabControlをTabStripのように使いたい
記事No6229
投稿日: 2007/09/04(Tue) 10:59
投稿者魔界の仮面弁士
> DataGridViewはTabPageに貼り付けという形がとれるようなので、
> その場合はTabPageの子コントロールということになるのでしょうか?

そうです。


> 今は上記のようなイメージをもっています。

Form1
└TabControl1
 ├TabPage1
 │└DataGridView1
 └TabPage2
  └DataGridView2

のように、ページごとに DataGridView を配置する方法と、

Form1
├TabControl1
│├TabPage1
│└TabPage2
└──DataGridView1

のように、TabPage には載せず、単に座標を重ねて配置しておき、
各ページで DataGridView を共有する方法とがあります。

どちらが使いやすいかは、ケースバイケースです。併用するのもアリでしょう。

[ツリー表示へ]
タイトルRe^4: TabControlをTabStripのように使いたい
記事No6230
投稿日: 2007/09/04(Tue) 14:19
投稿者皐月
魔界の仮面弁士さん、ありがとうございます。ようやく自分の思い通りの処理ができるようになりました。以下報告です。

    Private Sub TabControl1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles TabControl1.SelectedIndexChanged
        tabNo1 = CInt(TabControl1.SelectedIndex)
        ComboBox1.Text = tabNo1
        Call RefreshName()
    End Sub

    Private Sub RefreshName()
        Dim i As Short
        Name.Text = NameT

        With DataHeadGrid1
            For i = 0 To 31
                .Rows(i).Cells(0).Value = CommandName(tabNo1 * 30 + i)
            Next
        End With
    End Sub

教えていただいたSelectedIndexChangedを利用して、タブを切り替えたとき切り替えたページの30個分のデータを表示できるようになりました。
コンテナのことも知ることもでき、非常に勉強になりました。るしぇさん、ダンボさん、魔界の仮面弁士さん本当にありがとうございました。

[ツリー表示へ]
タイトルRe^5: TabControlをTabStripのように使いたい
記事No6231
投稿日: 2007/09/04(Tue) 15:28
投稿者魔界の仮面弁士
> tabNo1 = CInt(TabControl1.SelectedIndex)
> ComboBox1.Text = tabNo1

上記で使用している「tabNo1」の型は何ですか?
おそらくは Integer 型だと思いますが、もしそうならば CInt が冗長です。

tabNo1 が Integer 型なら、
 tabNo1 = TabControl1.SelectedIndex
 ComboBox1.Text = CStr(tabNo1)
にすべきですし、String 型なのであれば、
 tabNo1 = CStr(TabControl1.SelectedIndex)
 ComboBox1.Text = tabNo1
とすべきかと。


> .Rows(i).Cells(0).Value = CommandName(tabNo1 * 30 + i)
ここで使われている
 DataGridView1.Rows(行).Cells(列).Value = 新しい値
というアクセス方法のほかに、
 DataGridView1(列, 行).Value = 新しい値
という方法もありますね。

[ツリー表示へ]
タイトルRe^6: TabControlをTabStripのように使いたい
記事No6232
投稿日: 2007/09/04(Tue) 17:43
投稿者皐月
魔界の仮面弁士さん、ご指摘ありがとうございます。
tabNo1はInteger型です。早速修正いたしました。

> ここで使われている
>  DataGridView1.Rows(行).Cells(列).Value = 新しい値
> というアクセス方法のほかに、
>  DataGridView1(列, 行).Value = 新しい値
> という方法もありますね。

なるほど、こちらの方がソースがすっきりしますね。
丁寧なアドバイスありがたく頂戴いたします。

[ツリー表示へ]