動的に作成したコントロールについて

タグの編集
投稿者 SS  (中学生) 投稿日時 2011/3/26 17:57:13

動的に作成したタブページのプロパティに、アクセスするにはどうしたら良いでしょうか?
解答をよろしくお願いいたします。
投稿者 るきお  (社会人) 投稿日時 2011/3/26 20:54:35
情報はギブアンドテイクです。
>動的に作成したタブページのプロパティに、アクセスするにはどうしたら良いでしょうか?
ということであれば、動的にタブページを作成することはできているのですよね?
そのコードを書くようにしましょう。

さて、ご質問の件ですが、
私ならこのような書き方をします。
    
Dim newPage As New TabPage

TabControl1.TabPages.Add(newPage)

newPage.Text = "あいうえお"
newPage.BackColor = Color.Red
TabControl1.SelectedTab = newPage


次のように書くこともできます。
    
TabControl1.TabPages.Add("NewPage""あいうえお")

TabControl1.TabPages("NewPage").BackColor = Color.Blue
TabControl1.SelectedTab = TabControl1.TabPages("NewPage")


余談ですが、
>解答をよろしくお願いいたします。
この場合「解答」ではなく「回答」が適切かと思います。
投稿者 SS  (中学生) 投稿日時 2011/3/26 22:04:03
情報不足ですみませんでした。
るきおさんの回答からだと、同じイベント内での事となりますが
違うイベントからのアクセスは出来るのでしょうか?
下のコードで言うと、例えば「別のボタンを押したら、NewTabPage(下のコードで作った)のTextプロパティを"かきくけこ"にする」ということです。お願いいたします。
以下コードです。

'「pagenum」はただの変数です 
'「SPControl」はユーザーコントロールです。 
Private Sub ToolStripButton1_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles ToolStripButton1.Click
        Dim NewTabPage As New TabPage

        NewTabPage.Text = "◯ページ-" + pagenum
        
        Dim NewSPControl As New SPControl

        NewSPControl.Dock = DockStyle.Fill
        NewSPControl.Visible = True
        
        NewTabPage.Controls.Add(NewSPControl) 
        TabControl1.TabPages.Add(NewTabPage)
       
        pagenum += 1

  End Sub


※誤字訂正ありがとうございました。ミスでした。
投稿者 shu  (社会人) 投稿日時 2011/3/26 22:28:14
デザイン時に作成したコントロールをどうやって参照しているのか
という事と大差ありません。Designer.vbの中に答えはあります。
投稿者 るきお  (社会人) 投稿日時 2011/3/26 22:36:20
>違うイベントからのアクセスは出来るのでしょうか?
できます。

1番目の例では変数NewPageのスコープを他のイベント内でも見えるように変えるだけで実現できます。
2番目の例ではそのままで実現できます。

試してみてください。
投稿者 (削除されました)  () 投稿日時 2011/3/26 22:52:37
(削除されました)
投稿者 SS  (中学生) 投稿日時 2011/3/26 23:02:39
↑間違えました、すみません。

この場合ボタンを何回も押せるので、タブページはいくらでも作れます。
NewTabPageが複数作られた中の1つのプロパティにアクセスする場合も、変数NewPageのスコープを他のイベントで見えるように変えるだけでいいのでしょうか。
また、その場合
>変数NewPageのスコープを他のイベント内でも見えるように変えるだけで実現できます。
の具体的なやり方を教えていただけないでしょうか?
また、参考になるHP等ありましたらお願いします。るきおさん、shuさん、このような質問に付き合っていただきありがとうございます。
投稿者 SS  (中学生) 投稿日時 2011/3/26 23:09:50
上の
>NewTabPageが複数作られた中の~
の文が分かりにくかったので少しは分かりやすく訂正します。

訂正:
>NewTabPageが複数作られた中の1つのプロパティにアクセスする場合も、変数NewPageのスコープを他のイベントで見えるように変えるだけでいいのでしょうか。

分かりやすい文:
同じ名前で作られたコントロールのうちの、1つのコントロールのプロパティにアクセスするにはどうしたら良いでしょうか。その場合も変数NewPageのスコープを他のイベントで見えるように変えるだけでいいのでしょうか。
投稿者 shu  (社会人) 投稿日時 2011/3/26 23:14:00
複数あるならそれぞれのページ毎の変数が必要になるでしょう。
まとめたければ配列とかリストとかを使用すると良いかと思います。
投稿者 るきお  (社会人) 投稿日時 2011/3/26 23:34:06
>同じ名前で作られたコントロールのうちの、1つのコントロールのプロパティにアクセスするにはどうしたら良いでしょうか。
コントロール(=TabPage)は複数作成されるということですね?
で、そのうち1つのコントロールのプロパティにアクセスしたいということですが、
どの1つでしょうか?
最初の1つですか?最後の1つですか?
それとも何か別の見分ける方法を考えていますか?

それがわからなければ具体的なやり方はかけないです。

>その場合も変数NewPageのスコープを他のイベントで見えるように変えるだけでいいのでしょうか。 
複数を想定するのであればこれだけではだめです。
ダメな理由は変数が1個しかないから複数のTabPageを管理できないからです。
なので考え方的にはあっていますが、それだけではダメということです。

解決方法はshuさんが書き込みされている通りです。

具体的なやり方は上述の質問の答えが分からないと紹介できません。




投稿者 SS  (中学生) 投稿日時 2011/3/27 19:47:11
この回答が的外れかも知れませんが、
>それとも何か別の見分ける方法を考えていますか?
TabPageが追加されるときに「○ページ1」「○ページ2」...とTextプロパティを変えていっています。
それで区別がつかないでしょうか?それだけではダメでしょうか?
投稿者 るきお  (社会人) 投稿日時 2011/3/27 19:55:26
>TabPageが追加されるときに「○ページ1」「○ページ2」...とTextプロパティを変えていっています。
>それで区別がつかないでしょうか?それだけではダメでしょうか? 
OKです。

で、SSさんの知りたいことは
>同じ名前で作られたコントロールのうちの、1つのコントロールのプロパティにアクセスするにはどうしたら良いでしょうか。
ですよね。

なので、「○ページ1」と「○ページ2」、…のすべてのプロパティを設定したり取得したりするのではなく、
どれか1つのプロパティを設定したり取得したりしたいのだと思っています。
そのどれか1つとはどれですか?
たぶん固定で決まっているわけではないと思うので、そのときの『状況』に応じて判断して対象のページを指定することになると思うのですが、その判断はどうしたらいいですか?
一番番号の大きいページという判断でいいでしょうか?
それとも、一番番号の小さいページですか?
または、ほかの何かでしょうか?

それがわからないと、何のプロパティにアクセスすればいいかわからないので、具体的なやり方が書けないです。
投稿者 SS  (中学生) 投稿日時 2011/3/27 21:05:13
>そのどれか1つとはどれですか?
Textプロパティです。なのでそのTabPageのTextプロパティにアクセス、内容をいじった後に、いじった後のTextプロパティをなにかしらの変数に代入し、次回アクセスするときに今度はその変数で区別するような感じでいいと思います。お願いします。
>たぶん固定で決まっているわけではないと思うので、そのときの『状況』に応じて判断して対象のページを指定することになると思うのですが、その判断はどうしたらいいですか?
いままで書いていませんでしたが、対象のページの中にあるコントロールからです。今作っているのは、タブ型のウェブブラウザで、タブの中のコントロールをユーザコントロールにまとめてあり、そのユーザーコントロールの中のウェブブラウザコントロールのDocumentCompletedイベントが発生した時に、そのタブページのTextプロパティを、そのウェブブラウザのDocumentTitleにするということです。
単純に言えば、タブブラウザのタブの部分に、ページ名を表示させたいということです。
 
投稿者 SS  (中学生) 投稿日時 2011/3/27 21:06:44
わかりにくいので画像(?)を
_______________
「□ウィンドウ           ×  |
| ___________________                            |
|_|TabPage      |____________________________|
| _____________________________________________  |
||           UserControl                 |  |
||  _________________________________________  |  |         
|| |         WebBrowser               | |  |
|| |_________________________________________| |  |
||_____________________________________________|  |
|________________________________________________|
投稿者 (削除されました)  () 投稿日時 2011/3/27 21:12:42
(削除されました)
投稿者 shu  (社会人) 投稿日時 2011/3/27 21:15:02
ToolStripButton1を2回以上クリックしてから
別のボタンをクリックしたらどうしますか?
投稿者 SS  (中学生) 投稿日時 2011/3/27 23:05:16
といいますと?失礼ですがよく意味がわかりません。別のボタンというのは例えばどういうボタンですか?
投稿者 るきお  (社会人) 投稿日時 2011/3/27 23:37:30
なかなか話のすれちがいが解消できませんね。
>別のボタンというのは例えばどういうボタンですか? 
タブページを追加するボタンです。

とりえあず、
「DocumentCompleteイベントが発生したときに、そのWebBrowserコントロールが配置されているTabPageのTextプロパティを変更したい」ということがわかりましたので、多少具体的なコードが書けます。

Public Class Form1

    Private Sub ToolStripButton1_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles ToolStripButton1.Click

        Dim newPage As New TabPage
        newPage.Text = "新しいページ"

        Dim browser As New WebBrowser
        browser.Dock = DockStyle.Fill
        AddHandler browser.DocumentCompleted, AddressOf WebBrowser1_DocumentCompleted
        newPage.Controls.Add(browser)

        TabControl1.TabPages.Add(newPage)
        TabControl1.SelectedTab = newPage

        browser.Navigate("http://www.nifty.com")

    End Sub

    Private Sub WebBrowser1_DocumentCompleted(ByVal sender As System.ObjectByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs)

        Dim page As TabPage = sender.Parent

        page.Text = sender.DocumentTitle

    End Sub

End Class


この例はTabPageに直接WebBrowserコントロールが配置されているときにはうまく動きます。
DocumentCompleteイベントでsender.ParentがTabPageだからです。
SSさんの場合、さらにUserControlでくるまれているので、このUserControlのParentを取得するようにすればうまくいくはずです。
投稿者 SS  (中学生) 投稿日時 2011/3/28 15:13:14
るきおさん、shuさん、今回は付き合っていただきありがとうございました。ユーザーコントロールのParentを取得するようにしてやってみます。また何か質問があればこの掲示板を利用させていただきます。丁寧でわかりやすい解説、ありがとうございました。
投稿者 (削除されました)  () 投稿日時 2011/3/28 15:25:11
(削除されました)
投稿者 shu  (社会人) 投稿日時 2011/3/28 15:28:24
> といいますと?失礼ですがよく意味がわかりません。別のボタンというのは例えばどういうボタンですか? 

2011/3/26 22:04:03 にSSさん自身が書かれた別のボタンのことです。

処理イベントが変わっていたのは書込みタイミングで気づきませんでした。
投稿者 SS  (中学生) 投稿日時 2011/3/30 23:21:33
 Dim uc As Object 
Public Sub ToolStripButton1_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles ToolStripButton1.Click
        Dim newpage As New TabPage
        newpage.Text = "NewPage"

        Dim browser As New SPControl
        browser.Dock = DockStyle.Fill
        uc = browser

        AddHandler browser.WebBrowser.DocumentCompleted, AddressOf WebBrowser1_DocumentCompleted
        newpage.Controls.Add(browser)

        TabControl1.TabPages.Add(newpage)

        TabControl1.SelectedTab = newpage
       
    End Sub

Public Sub WebBrowser1_DocumentCompleted(ByVal sender As System.ObjectByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs)
       
        Dim page As TabPage = uc.Parent


        page.Text = sender.DocumentTitle

    End Sub


End Class

すみません。これだと一番最後に追加したタブページのみのページタイトルが更新されます。どうしたら良いでしょうか?
投稿者 るきお  (社会人) 投稿日時 2011/3/30 23:41:20
>Dim page As TabPage = uc.Parent
これがダメです。

ページは複数あるのに対し、ucという変数は1つしかありませんよね?
なので、この構造では複数のページを操ることは無理です。

senderからページを取得するように改造してください。
今回のケースではsenderの内容はWebBrowserですが、
そのWebBrowserが配置されているSPControlのことがわからないので何とも言えません。

たとえば、
Dim page As TabPage = sender.Parent.Parent
でうまくいくかもしれませんし、ダメかもしれません。
Dim page As TabPage = sender.Parent.Parent.Parent
でうまくいくかもしれませんし、ダメかもしれません。

自作のユーザーコントロール等作成するときは一般的なアドバイスが受けられなくなる覚悟が必要です。
投稿者 るきお  (社会人) 投稿日時 2011/3/30 23:48:38
あ、でも、
>AddHandler browser.WebBrowser.DocumentCompleted, AddressOf WebBrowser1_DocumentCompleted
これを見ると、SPControlの構造がちょっと想像できました。

やっぱり、これが最有力です。
Dim page As TabPage = sender.Parent.Parent
投稿者 SS  (中学生) 投稿日時 2011/3/31 15:34:19
ありがとうございました。これで本当の解決です。

Dim page As TabPage = sender.Parent.Parent.Parent

でできました。