ListView と同時実行性に関する典型的な問題で立ち往生しています。コードビハインドでバインドしているListViewがあります(SQLDataSourceを使用していません)。
- Page_Load の ListView を、データベースから返されたコレクションにバインドします。
- 「ItemEditing」イベントハンドラーで「編集」コマンドを次のように処理します。
Me.MyListView.EditIndex = e.NewEditIndex;
BindMyListView();
Me.MyListView.InsertItem.Visible = False;
- その他の操作は
ItemInserting
、ItemUpdating
、ItemDeleting
などを通じて同じ方法で処理されます。
ページを参照すると、ListView が正常に表示されます。「編集」コマンド リンクをクリックすると、ListView が適切に編集モードになります。「保存」コマンドリンクをクリックすると、レコードが完全に保存されます。すべて良い。
問題は、ListView がページに読み込まれ、他のユーザーがそのレコードの [編集] をクリックする直前にレコードを削除したときに始まります。ListView は編集モードになりますが、次の行になります。レコードを削除するときも同じことが起こります。「削除」をクリックする直前に他のユーザーがレコードを削除すると、次のレコードが削除されます。
いろいろいじった後、フレームワークで使用されているのは「インデックス」であることがわかりました。そのため、レコードが既に削除されている場合、ListView が (ポストバック時に) 再度バインドされると、インデックスは次のレコードを指すようになります!
これを回避することはできません。「CommandArgument」を使用してみましたが、次の行の引数も返されます。ListView が Page_Load 中にバインドされると、編集インデックス ポインターは次のレコードになり、「CommandArgument」には次の行の引数が含まれます。
皆さんからの助けが必要です。
ありがとう/ @bhi
完全なコードは次のとおりです。正常に動作しますが、上記の問題があります。
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
PrepareListView()
End Sub
Private Sub BindMyListView()
Dim items = BusinessLogic.GetData()
Me.MyListView.DataSource = items
Me.MyListView.DataBind()
End Sub
Private Sub MyListView_ItemCanceling(sender As Object, e As System.Web.UI.WebControls.ListViewCancelEventArgs) Handles MyListView.ItemCanceling
e.Cancel = True
Me.MyListView.EditIndex = -1
BindMyListView()
Me.MyListView.InsertItem.Visible = True
End Sub
Private Sub MyListView_ItemDeleting(sender As Object, e As System.Web.UI.WebControls.ListViewDeleteEventArgs) Handles MyListView.ItemDeleting
Dim autoId As Integer = 0
autoId = Integer.Parse(Me.MyListView.DataKeys(e.ItemIndex).Value.ToString)
BusinessLogic.Delete(autoId)
BindMyListView()
End Sub
Private Sub MyListView_ItemEditing(sender As Object, e As System.Web.UI.WebControls.ListViewEditEventArgs) Handles MyListView.ItemEditing
Me.MyListView.EditIndex = e.NewEditIndex
BindMyListView()
Me.MyListView.InsertItem.Visible = False
End Sub
Private Sub MyListView_ItemInserting(sender As Object, e As System.Web.UI.WebControls.ListViewInsertEventArgs) Handles MyListView.ItemInserting
Dim item As DomainModel.DataObject = New DomainModel.DataObject
item.Id = 0
item.DataValue = DirectCast(e.Item.FindControl("txtDataValue"), TextBox).Text
BusinessLogic.Save(item)
BindMyListView()
End Sub
Private Sub MyListView_ItemUpdating(sender As Object, e As System.Web.UI.WebControls.ListViewUpdateEventArgs) Handles MyListView.ItemUpdating
Dim item As DomainModel.DataObject = New DomainModel.DataObject
item.Id = Integer.Parse(Me.MyListView.DataKeys(e.ItemIndex).Value.ToString)
item.DataValue = DirectCast(Me.MyListView.Items(e.ItemIndex).FindControl("txtDataValue"), TextBox).Text
BusinessLogic.Save(item)
Me.MyListView.EditIndex = -1
BindMyListView()
End Sub