tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
[ツリー表示へ]  [ワード検索]  [Home]

タイトル Re^7: 文字列によるプロパティの参照
投稿日: 2012/01/23(Mon) 15:34
投稿者魔界の仮面弁士
> 直ぐに回答してくださってたんですね、ありがとうございます。m(_ _)m
質問内容の把握が追いついていないので、回りくどい回答に
なっている可能性もありますがご容赦を…。


> 比較対象は、フォーム生成元のフォームだけです。
(中略)
> 以後、生成元フォーム→form1、生成フォーム→form2 とします。
「フォーム生成元のフォーム」について確認させてください。最初の質問は、
『ユーザーコントロールから別のフォーム上のコントロールのプロパティを読みたい』
でしたよね。

フォームの表示処理は、
  Dim 子 As New フォーム型()
  子.Show(親)
または、
  Using 子 As New フォーム型()
    子.ShowDialog(親)
  End Using
などとして呼び出しているものと推測しますが、ここでいう form1 というのは、

 (1) 「New でフォームを生成する処理」が書かれているフォーム

 (2) 「Show/ShowDialog での呼び出し処理」が書かれているフォーム

 (3) 子フォームのオーナー(上記でいうところの [親]の部分)

のうち、いずれを指しているのでしょうか。(1=2=3 な場合もありますが)
(フォーム生成元というだけあって、1 の事なのかな…)



> プロパティP1…P20…として管理しています。
それぞれのプロパティに関連性があるのですよね?

同種のものであれば、
 (1) foo.P(1) などとアクセスできるよう「引数付きプロパティ」にまとめる。
 (2) 配列を返すプロパティを追加する
 (3) コレクションを返すプロパティを追加する
なども用意しておくと便利かも。


> 重複判定は uctrlAns に付けようと思っています。
ごめんなさい、何と何の重複を判定するのか、まだ把握できていません。

(1) 別々のコントロールの同名プロパティの値重複。
たとえば、Form1.uctrlAns1.P1 と Form2.uctrlAns1.P1 と Form3.uctrlAns1.P1 を比較。

(2) 別々のコントロールの全プロパティの値重複。
Form1.uctrlAns1.P1〜20 と Form2.uctrlAns1.P1〜20 と Form3.uctrlAns1.P1〜20 を比較。

(3) 同一フォーム上の同一コントロール内での全プロパティの値重複。
Form1.uctrlAns1.P1 と Form1.uctrlAns1.P2 と Form1.uctrlAns1.P3 を比較。

(4) 同一フォーム上の別々のコントロール上の同名プロパティの値重複。
たとえば、Form1.uctrlAns1.P1 と Form1.uctrlAns2.P1 と Form1.uctrlAns3.P1 を比較。

など。理解が覚束なくて申し訳ない…。


> form2 の P1 を項目名を描画する際、form1.uctrlAns.P1…P20を調べなくてはならないので
> 20回のアクセス。
データをコレクション等で管理しておけば、プロパティを分けずとも、
一度に値を受け渡せるようになるかと思います。

プロパティ自体は分けておきたいのだとしても、たとえば
 Public GetPValues(ByRef p1 As foo, ByRef p2 As foo, …)
という 20 個の出力引数(ByRef)を持つメソッドを通じて値を受け取らせたり、
あるいは――
 「Public P(1 To 20) As 何某」な配列とか、
 「20行のレコードを持った DataTable」とか
 「20列のレコードを持った DataTable」とか
 「P1〜P20 というプロパティを持つクラスや構造体」
――を返すプロパティを用意するという手もあります。

DataTable にしておけば、データの並び替えや条件検索も
DataView を通じて容易に行えるというメリットがあります。

これが VB2008 なら、Linq を使ってさらに簡単にできるのですけれどね。


> 私が思っていたのは、インデックスではなく、項目名を指定して値が取得できる配列です。
VB だと、Dictionary(Of TKey, TValue) クラスが該当します。
あるいは DataTable とか。

'コレクションの宣言
Dim col As New Dictionary(Of String, Date)()

'データと名前を追加
col.Add("P1", Now)  'Add メソッドでの追加
col("P5") = Today   'インデクサでの新規追加
'col.Add("P5", Now) '同じ名前での重複登録はNG

'名前による取得
ListBox1.Items.Add(col("P1"))
ListBox1.Items.Add(col!P5)      'ディクショナリ アクセス演算子での呼び出しも可
'ListBox1.Items.Add(col("P0"))  '未登録の名前を参照するのは NG


'値の書き換えも可能
col("P1") = #1/23/2012 3:00:00 PM#

'名前の削除もできる
col.Remove("P0")    '既存の名前を指定して削除(戻り値 True)
col.Remove("P9")    '未登録の値でも削除はできる(戻り値 False)

'名前が存在しているか?
If Not col.ContainsKey("P0") Then
    MsgBox("キーP0は未登録です")
End If

'For Each での列挙が可能
For Each p As KeyValuePair(Of String, Date) In col
    ListBox2.Items.Add(p.Key)
    ListBox3.Items.Add(p.Value)
Next


> ゆくゆくは、イベントで双方向に出来ればいいなって思っています。
双方向なら、データバインドを利用すると便利かもしれません。

データソースと データコンシューマの間で双方向にやりとりできますし、
同じデータを複数個所で参照していれば、それらすべてに変更が通知されますので。


Private tbl As New DataTable()
Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
    tbl.Columns.Add("P1", GetType(String))
    tbl.Columns.Add("P2", GetType(String))
    tbl.Rows.Add("123", "456")
    tbl.Rows.Add("789", "987")
    tbl.Rows.Add("654", "321")
    tbl.AcceptChanges()

    ListBox1.DataSource = tbl
    ListBox1.DisplayMember = "P1"

    DataGridView1.DataSource = tbl
End Sub

Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
    tbl.Rows(2)("P1") = "TEST"
End Sub

- 関連一覧ツリー をクリックするとツリー全体を一括表示します)

古いスレッドにレスはつけられません。