- PR -

[vb.net]TextBox + Combobox で DataGridViewComboBoxColumn.DataPropertyName と同様な機能を実装したい

投稿者投稿内容
とある根性なし
ベテラン
会議室デビュー日: 2006/08/15
投稿数: 54
投稿日時: 2007-12-04 20:47
ぉおぅ?
アドバイスに従い、もう一度 On*** でプロシージャ書いたらうまくいきました・・・
なんで最初うまくいかなかったんだろ
もうそのときのコードが残ってないのでなんとも言えないですね

引用:

R・田中一郎さんの書き込み (2007-12-04 19:36) より:

ComboBox を継承したクラスで TextBox をどうやって実装しているのかは不明ですが。


ComboBox を継承したクラスでは、TextBox に対する処理は入力チェックくらいしかしてません。
Me.FindForm で親になるフォームを拾って、
Form.Controls(追加したプロパティの値) があったら、
OnEnter なら、Me.SelectedValue = Form.Controls().Text、
OnValited なら、Form.Controls().Text = Me.SelectedValue
としています。
せっかくなので、ソースも載せておきます。

ComboBox.SelectedIndex = "0" はつねに
.SelectedValue = "0" 、.Text = " " とします。
おかしなところがあったら、教えてください
# コメントは、今つけた適当なものです。

コード:

※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
※ このコードの提示当初、バグがありました。
※ ペアのコントロールが、GroupBox や Panel 等のコンテナ上に配置されている場合、
※ 正しく機能しませんでした。
※ 以下のものは修正版です。
※ (さらに修正が加わっています。)
※  万 が 一 コピーして持っていってくださった方がいらっしゃいましたら、
※ 修正していただいた上、もう一度十分なテストを行っていただくようお願いします。
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
''' -----------------------------------------------------------------------------
''' <summary>
''' SelectedValue の値を自動でペアになるコントロールの
'''    Text プロパティと同期を取る ComboBox クラス </summary>
''' -----------------------------------------------------------------------------
Public Class LinkageComboBox
Inherits System.Windows.Forms.ComboBox

' コンストラクタ
Public Sub New()
MyBase.New()
Me.DataPropertyName = String.Empty
End Sub

' ペアのコントロールの名前
Private _DataPropertyName As String

' _DataPropertyName の窓口
<System.ComponentModel.Category("動作"), _
System.ComponentModel.Description("アイテムのコードを入力する Textプロパティを持つ" _
& "コントロールの名前を設定します。")> _
Public Property DataPropertyName() As String
Get
Return Me._DataPropertyName
End Get

Set(ByVal value As String)
Me._DataPropertyName = value
End Set
End Property

' 未選択状態の値
Dim notSelected As Integer = -1

' フォーカスを受取ったとき、ペアのコントロールの Text を ValueMember にセットする
Protected Overrides Sub OnEnter(ByVal e As EventArgs)
Try
Dim pair As Control = GetPair()
If IsNothing(pair) Then Exit Sub
Me.SelectedIndex = notSelected
If String.IsNullOrEmpty(pair.Text) Then Exit Sub

Dim tbl As Data.DataTable = DirectCast(Me.DataSource, Data.DataTable)
Dim row As Data.DataRow
For Each row In tbl.Rows
If row.Item(Me.ValueMember).ToString = pair.Text.ToString Then
Me.SelectedValue = pair.Text
Exit Sub
End If
Next
Finally
MyBase.OnEnter(e)
End Try
End Sub

' フォーカスが離れるとき、ペアのコントロールに ValueMember をセットする
Protected Overrides Sub OnValidated(ByVal e As System.EventArgs)
Try
If Me.SelectedIndex = notSelected Then Exit Sub
Dim pair As Control = GetPair()
If IsNothing(pair) Then Exit Sub
pair.Text = Me.SelectedValue.ToString
Finally
MyBase.OnValidated(e)
End Try
End Sub

' ペアのコントロールを探すプロシージャ
Private Function GetPair() As Control
If _DataPropertyName = String.Empty Then Return Nothing
Dim parent As Control = Me.Parent
Dim pair As Control = parent.Controls(_DataPropertyName)
Do While (IsNothing(pair))
If Object.Equals(parent, Me.FindForm) Then Return Nothing
parent = parent.Parent
pair = parent.Controls(_DataPropertyName)
Loop
Return pair
End Function
End Class




[ メッセージ編集済み 編集者: とある根性なし 編集日時 2007-12-04 21:04 ]

[ メッセージ編集済み 編集者: とある根性なし 編集日時 2007-12-04 21:08 ]

[ メッセージ編集済み 編集者: とある根性なし 編集日時 2007-12-05 21:18 ]

[ メッセージ編集済み 編集者: とある根性なし 編集日時 2007-12-07 18:51 ]
R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2007-12-05 09:18
なるほどなるほど、TextBox は別のコントロールとして DataPropertyName で連携させてたんですね。
理解できました^^;

_________________
R・田中一郎 -  R.Tanaka.Ichiro’s Blog
とある根性なし
ベテラン
会議室デビュー日: 2006/08/15
投稿数: 54
投稿日時: 2007-12-05 10:23
あ。
ちょっと応用して、DataPropertyName の示すコントロールの種類を判定して、
TextBox だったら従来どおりで、
ComboBox だったら SelectedValue にセットしたり
(ニーズなさそうですけど、コードのComboBoxと名称のComboBox分けたりとか)
できますね。

どなたかの参考になれば幸いです。
とある根性なし
ベテラン
会議室デビュー日: 2006/08/15
投稿数: 54
投稿日時: 2007-12-05 21:11
私の(2007-12-04 20:47)のレスで提示したソースにバグがありました。
ご覧いただいた方、確認よろしくお願いします。

このレスで修正版を載せるか直接修正するか考えましたが、このような形にしました。
おかしければ教えてください。
次からは訂正します。
とある根性なし
ベテラン
会議室デビュー日: 2006/08/15
投稿数: 54
投稿日時: 2007-12-07 19:02
たびたび申し訳ありませんが、
(2007-12-04 20:47)のソースを再度修正しました。
ご確認ください。

スキルアップ/キャリアアップ(JOB@IT)