アプリ版:「スタンプのみでお礼する」機能のリリースについて

VB2010です。

DataGridViewのDataSourceにコレクションを設定しており、
このコレクションのアイテムを指定してDataGridViewに表示されている行インデックスを取得したい。

以下、現状のコードです。Form1にDataGridView、ボタン、テキストボックスを貼り付けており、
テキストボックスに名前を入力してボタンをおすとその行を選択状態とします。

行を取得するために行頭から順に調べておりますが、
アイテムを指定して行を参照できるようなプロパティなり
なにか良い方法が無いでしょうか?

Public Class Form1

Private _persons As Collection

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
_persons = New Collection
_persons.Add(New Person With {.Name = "あかい", .Age = 10}, "あかい")
_persons.Add(New Person With {.Name = "いまい", .Age = 13}, "いまい")
_persons.Add(New Person With {.Name = "うかい", .Age = 43}, "うかい")
_persons.Add(New Person With {.Name = "えのき", .Age = 8}, "えのき")
_persons.Add(New Person With {.Name = "おかの", .Age = 3}, "おかの")

DataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect
DataGridView1.DataSource = _persons

Dim col As New DataGridViewColumn
col = New DataGridViewTextBoxColumn
col.DataPropertyName = "Name"
col.Name = "NameField"
DataGridView1.Columns.Add(col)

col = New DataGridViewTextBoxColumn
col.DataPropertyName = "Age"
col.Name = "AgeField"
DataGridView1.Columns.Add(col)

End Sub

Private Class Person
Public Property Name As String
Public Property Age As Integer
End Class

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim name As String = TextBox1.Text
If name.Length = 0 Then Return
If Not _persons.Contains(name) Then Return
Dim person As Person = _persons.Item(name)
For i As Integer = 0 To DataGridView1.Rows.Count - 1
Dim rowItem As Person = DataGridView1.Rows(i).DataBoundItem
If rowItem.Equals(person) Then
DataGridView1.Rows(i).Selected = True
End If
Next
End Sub
End Class

A 回答 (5件)

もう一ついい感じのものがありました。

KeyedCollection クラスです。

Private Class Person を Public Class Person に変更して Public Class Form の外に出さなければなりませんが、

Public Class Form1

Private Class Persons
Inherits System.Collections.ObjectModel.KeyedCollection(Of String, Person)

Protected Overrides Function GetKeyForItem(ByVal item As Person) As String
Return item.Name
End Function

Public Overloads Function IndexOf(ByVal name As String) As Integer
Return MyBase.IndexOf(MyBase.Item(name))
End Function

End Class

Private _persons As Persons

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
_persons = New Persons
_persons.Add(New Person With {.Name = "あかい", .Age = 10})
_persons.Add(New Person With {.Name = "いまい", .Age = 13})
_persons.Add(New Person With {.Name = "うかい", .Age = 43})
_persons.Add(New Person With {.Name = "えのき", .Age = 8})
_persons.Add(New Person With {.Name = "おかの", .Age = 3})

DataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect
DataGridView1.DataSource = _persons

Dim col As New DataGridViewColumn
col = New DataGridViewTextBoxColumn
col.DataPropertyName = "Name"
col.Name = "NameField"
DataGridView1.Columns.Add(col)

col = New DataGridViewTextBoxColumn
col.DataPropertyName = "Age"
col.Name = "AgeField"
DataGridView1.Columns.Add(col)

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim name As String = TextBox1.Text

Me.DataGridView1.Rows(_persons.IndexOf(name)).Selected = True
End Sub

End Class

という感じでできます。

参考URL:http://msdn.microsoft.com/ja-jp/library/ms132438 …
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

indexを勝手に振ってくれるわけですね。これは良さげです。

お礼日時:2011/06/01 11:39

Person に Index プロパティーを追加してやれば



Private Sub AddPerson(ByRef p As Person, ByVal key As String)

p.Index = _persons.Count

_persons.Add(p, key)

End Sub

でコレクションに追加して
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Dim p As Person = _persons.Item(Me.TextBox1.Text)

Me.DataGridView1.Rows(p.Index).Selected = True

End Sub

とできます。

Person に Index プロパティーを追加するというのが設計思想に反するかもしれませんが…。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
参考になります。
こういった機能が組み込まれていればいいんですけどね。

お礼日時:2011/06/01 08:59

すいません答えじゃないですが...



簡単なのは、CellFormattingイベントを使う。

ボタンを押した時に、それぞれセルのvalueにテキストボックスに入力されている値が
含まれているかInstr関数で判定。
含まれていれば、
.DefaultCellStyle.BackColorや
.DefaultCellStyle.ForeColorを変更するとか...

ただ、行番号(インデックス)のみを取得したいのであれば、
やはり、全行を確認するしかないのではないでしょうか...
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

データが多くなると全行確認したくないですが
仕方ないですね。

お礼日時:2011/05/31 12:47

No.1です。


ごめんなさい求めている答えじゃなかったですね^^;

この回答への補足

回答ありがとうございます。

(もしあればですが・・・)
Forを使わない方法をご教授いただきたく。

補足日時:2011/05/31 11:53
    • good
    • 0

datagridviewに主キーとなる列があるのなら...


もしくは、テキストボックスに入力する値が、他にはない場合...

'全行を比較
For Earc v As DatagridviewRow In Me.Datagridview.Rows

  'テキストと列("名前")の値が同じならその行を選択状態にし、カレント行とする。
  If Me.テキストボックス.Text = v.Cells("名前").Value Then
    Me.datagridview.CurrentCell = v.Cells("名前")
    v.Selected = True
    Exit For
  End If

Next

ただし、MultiSelectがTrueの場合は一旦datagridviewのカレント行を以下のように無くす必要があります。
Me.datagridview.CurrentCell = Nothing
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!