tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトル他画面にデータを表示する方法
記事No9666
投稿日: 2009/12/02(Wed) 11:23
投稿者いと
お世話になります。

現在、業務でVB2008の改造を行っております。

aaa画面(親)とbbb画面(子)がありaaa画面からボタン操作でbbb画面を表示しています。
それぞれにデータグリッドビューがあり次のことをしたいと思っています。

bbb画面のコード上でaaa画面のデータグリッドビューに
aaa.Rows.Add(0, "テスト")とすると”テスト”表示されますが、
aaa画面のコード上でbbb画面のデータグリッドビューに
bbb.Rows.Add(0, "テスト")とすると表示されません。
何か必要な処理があるのでしょうか?

よろしくお願いします。

[ツリー表示へ]
タイトルRe: 他画面にデータを表示する方法
記事No9667
投稿日: 2009/12/02(Wed) 12:00
投稿者魔界の仮面弁士
> bbb画面のコード上でaaa画面のデータグリッドビューに
> aaa.Rows.Add(0, "テスト")とすると”テスト”表示されますが、

[aaa]は、DataGridView ではなく、Form なのですよね。

Form に Rows プロパティは無いはずですが、上記コードが利用できるという事は、
もしかしてForm 上に、Rows というメンバを追加定義されているのでしょうか。


> aaa画面のコード上でbbb画面のデータグリッドビューに
> bbb.Rows.Add(0, "テスト")とすると表示されません。

表示されないとは言っても、特にエラーが出るわけではないのですね?

では変数 bbb が、bbb 画面(あるいは、bbb画面のデータグリッドビュー)を
表しているかどうかを確認してみてください。もしかしたらインスタンスの取り違えにより、
同名の画面がもう一つ(非表示で)生成され、そちらに追加されてしまっているのかも知れません。

[ツリー表示へ]
タイトルRe^2: 他画面にデータを表示する方法
記事No9668
投稿日: 2009/12/02(Wed) 12:28
投稿者いと
お返事ありがとうございます。

紛らわしくて申し訳ありません。
a画面にaaaというデータグリッドビュー
b画面にbbbというデータグリッドビュー
とさせてください。
エラーはでませんし、デバッガでそこを通るのですが表示されない状態です。
ちなみにバッググランドでスレッドを開始しています。
データグリッドビューの名称は確認してみました。



> [aaa]は、DataGridView ではなく、Form なのですよね。
> 表示されないとは言っても、特にエラーが出るわけではないのですね?

>
> では変数 bbb が、bbb 画面(あるいは、bbb画面のデータグリッドビュー)を
> 表しているかどうかを確認してみてください。もしかしたらインスタンスの取り違えにより、
> 同名の画面がもう一つ(非表示で)生成され、そちらに追加されてしまっているのかも知れません。

[ツリー表示へ]
タイトルRe^3: 他画面にデータを表示する方法
記事No9669
投稿日: 2009/12/02(Wed) 13:18
投稿者魔界の仮面弁士
> a画面にaaaというデータグリッドビュー
> b画面にbbbというデータグリッドビュー
> とさせてください。

であれば、
 [a画面のインスタンス].aaa.Rows.Add(0, "テスト")
 [b画面のインスタンス].bbb.Rows.Add(0, "テスト")
というコードになるかと思います。あまり良い設計手法ではありませんけれどね。

[ツリー表示へ]
タイトルRe^4: 他画面にデータを表示する方法
記事No9670
投稿日: 2009/12/02(Wed) 13:38
投稿者いと
> であれば、
>  [a画面のインスタンス].aaa.Rows.Add(0, "テスト")
>  [b画面のインスタンス].bbb.Rows.Add(0, "テスト")
> というコードになるかと思います。あまり良い設計手法ではありませんけれどね。

a.bbb.Rows.Add(0, "テスト")
というようにはしていますが表示されません。

b.aaa.Rows.Add(0, "テスト")
は表示されます。

[ツリー表示へ]
タイトルRe^4: 他画面にデータを表示する方法
記事No9671
投稿日: 2009/12/02(Wed) 13:44
投稿者るしぇ
魔界の仮面弁士さんと同じく、良くない設計であることだけ先に言っておきます。
通常は、そのフォームのコントロールはそのフォーム自身が操作するようにします。
外部からデータを表示させたい場合は、一度自作のプロパティ経由などでフォーム
にデータを渡しておき、フォームがそのタイミングで自分のコントロールに表示
するように設計します。
外部(他の画面やプログラム)が直接コントロールを操作するような設計は避けます。

それは置いておいて、インスタンスの管理が理解できておらず、非表示のb画面が
複数できているのでしょうね。
魔界の仮面弁士さんの書き込みの補足でデータを設定していると思っている
コードの直前で、その対象を表示する命令を入れてみてください。

[b画面のインスタンス].Show
>[b画面のインスタンス].bbb.Rows.Add(0, "テスト")

画面がもう一つ表示されたら、そのような命令を出している(コードで書いている)
のが原因です。

[ツリー表示へ]
タイトルRe^5: 他画面にデータを表示する方法
記事No9672
投稿日: 2009/12/02(Wed) 14:19
投稿者いと
> [b画面のインスタンス].Show
> >[b画面のインスタンス].bbb.Rows.Add(0, "テスト")
>
> 画面がもう一つ表示されたら、そのような命令を出している(コードで書いている)
> のが原因です。

上記を行ってみましたが画面は表示されませんでした。
一つ質問なのですが、処理開始ボタン押下でスレッドを開始しています。
スレッド開始する前は正しく表示されたのでスレッドと何か関係があるのでしょうか?

[ツリー表示へ]
タイトルRe^6: 他画面にデータを表示する方法
記事No9673
投稿日: 2009/12/02(Wed) 14:45
投稿者魔界の仮面弁士
一般的には、コントロールの操作は自フォームのみで行うべきです。
別フォームに操作させる事は、極力避けるようにしてください。

まして、a と b を互いに操作させあうようなコードにしてしまうと、
画面数の増減などの仕様変更に弱くなってしまいますし、
他プロジェクトなどへ流用する事も困難になってしまいがちです。


> 一つ質問なのですが、処理開始ボタン押下でスレッドを開始しています。
> スレッド開始する前は正しく表示されたのでスレッドと何か関係があるのでしょうか?

そのワーカースレッドと、画面側(メインスレッド)の関係はどのようになっていますか?
通常、画面を操作するのはメインスレッドのみとなり、ワーカースレッドから
画面を直接操作する事はできません。


もしも画面 a と b が異なるスレッドに存在しているのだとしたら、
a 側から『b.bbb.Rows.Add(0, "テスト")』や
『[b画面のインスタンス].bbb.Rows.Add(0, "テスト")』を
呼び出す事はできません。イベントや BeginInvoke などを通じて、
「bbb の操作を b に依頼する」ような実装にする必要があります。

[ツリー表示へ]
タイトルRe^7: 他画面にデータを表示する方法
記事No9698
投稿日: 2009/12/04(Fri) 13:10
投稿者いと
返事が大変おそくなりました。
参考にさせていただきたいと思います。

> 一般的には、コントロールの操作は自フォームのみで行うべきです。
> 別フォームに操作させる事は、極力避けるようにしてください。
>
> まして、a と b を互いに操作させあうようなコードにしてしまうと、
> 画面数の増減などの仕様変更に弱くなってしまいますし、
> 他プロジェクトなどへ流用する事も困難になってしまいがちです。
>
>
> > 一つ質問なのですが、処理開始ボタン押下でスレッドを開始しています。
> > スレッド開始する前は正しく表示されたのでスレッドと何か関係があるのでしょうか?
>
> そのワーカースレッドと、画面側(メインスレッド)の関係はどのようになっていますか?
> 通常、画面を操作するのはメインスレッドのみとなり、ワーカースレッドから
> 画面を直接操作する事はできません。
>
>
> もしも画面 a と b が異なるスレッドに存在しているのだとしたら、
> a 側から『b.bbb.Rows.Add(0, "テスト")』や
> 『[b画面のインスタンス].bbb.Rows.Add(0, "テスト")』を
> 呼び出す事はできません。イベントや BeginInvoke などを通じて、
> 「bbb の操作を b に依頼する」ような実装にする必要があります。

[ツリー表示へ]
タイトルRe^8: 他画面にデータを表示する方法
記事No9701
投稿日: 2009/12/04(Fri) 15:33
投稿者いと
b画面のボタンクリックで処理が開始し、a画面側の関数を呼び、そこでスレッドを
生成しています。その中でエラーが発生した場合にb画面のデータグリッドビュー
にメッセージ表示したいと思いました。。

エラー発生時a画面で
b.HistoryLog("123")

b画面で
Delegate Sub dgvLog111(ByVal log As String)
Dim dgvLog222 As New dgvLog111(AddressOf HistoryLog)

Public Sub HistoryLog(ByVal text As String)

    If Me.bbb.InvokeRequired = True Then
        Me.Invoke(dgvLog222, New Object() {text})
    Else
        Me.bbb.Rows.Insert(0, text)
    End If
End Sub

しかしながら、表示されませんでした。
何が問題かわかりません。
よろしくお願いします。

> > もしも画面 a と b が異なるスレッドに存在しているのだとしたら、
> > a 側から『b.bbb.Rows.Add(0, "テスト")』や
> > 『[b画面のインスタンス].bbb.Rows.Add(0, "テスト")』を
> > 呼び出す事はできません。イベントや BeginInvoke などを通じて、
> > 「bbb の操作を b に依頼する」ような実装にする必要があります。

[ツリー表示へ]
タイトルRe^9: 他画面にデータを表示する方法
記事No9708
投稿日: 2009/12/07(Mon) 17:15
投稿者いと
> b画面のボタンクリックで処理が開始し、a画面側の関数を呼び、そこでスレッドを
> 生成しています。その中でエラーが発生した場合にb画面のデータグリッドビュー
> にメッセージ表示したいと思いました。。
>
> エラー発生時a画面で
> b.HistoryLog("123")
>
> b画面で
> Delegate Sub dgvLog111(ByVal log As String)
> Dim dgvLog222 As New dgvLog111(AddressOf HistoryLog)
>
> Public Sub HistoryLog(ByVal text As String)
>
>     If Me.bbb.InvokeRequired = True Then
>         Me.Invoke(dgvLog222, New Object() {text})     ←−−
>     Else
>         Me.bbb.Rows.Insert(0, text)
>     End If
> End Sub
>
これを実行すると、←行の処理を通りませんでした。IF文をコメントアウトして無理やり処理を通すと”ウィンドウ ハンドルが作成される前、コントロールで Invoke または BeginInvoke を呼び出せません。”とエラーが出てしまいました。
Insertのみですと表示されません。
ご教示よろしくお願いします。

[ツリー表示へ]
タイトルRe^10: 他画面にデータを表示する方法
記事No9739
投稿日: 2009/12/19(Sat) 14:24
投稿者るしぇ
スレッドをどう管理しているかが問題になるわけですが、
デリゲートによるマルチスレッドを理解する為に、魔界の仮面弁士さんご指摘の
BeginInvoke については調べたのでしょうか?
http://www.atmarkit.co.jp/fdotnet/mthread/mthread02/mthread02_01.html

[ツリー表示へ]