将数据从数据绑定列表框移到未绑定列表框并返回VB.NET [英] Moving Data From Databound Listbox To Unbound Listbox And Back VB.NET
问题描述
因此,我一直在浏览,并且有很多关于如何将数据从列表框移动到列表框的说明.
我有一个列表框绑定到我的SQL Server的源,而另一个未绑定.我的目标是将数据从第一个(LBsearch)
移至第二个(LBselect)
并移回.我见过有人说用
LBselect.Items.Add(LBsearch.SelectedItem)
,但是它不返回数据,而是显示System.Data.DataRowView
.我已经尝试了许多不同的后缀,并且除了LBsearch.text
以外都显示了此后缀.然后从第一个删除数据,我一直在删除databindingsource (PersonBindingSource)
PersonBindingSource.Remove(LBsearch.SelectedItem)
,但是我的问题是再次添加数据.
So I have been browsing about and there are a lot of explanations on how to move data from listbox to listbox.
I have a listbox bound to a source from my SQL server and another unbound. My aim is to move the data from the first (LBsearch)
to the second (LBselect)
and back. I have seen people say use
LBselect.Items.Add(LBsearch.SelectedItem)
however it doesn't return data and instead shows System.Data.DataRowView
. I've tried many different suffixes and all show this apart from LBsearch.text
. Then to remove the data from the first one I've been removing the databindingsource (PersonBindingSource)
with
PersonBindingSource.Remove(LBsearch.SelectedItem)
but my issue is adding the data back again.
PersonBindingSource.Add(LBselect.SelectedItem)
给出错误:
System.InvalidOperationException: Objects added to a BindingSource's list must all be of the same type.
at System.Windows.Forms.BindingSource.Add(Object value)
at Project_Program.Participants.btnremoveselect_Click(Object sender, EventArgs e) in E:\Documents\Visual Studio\Project Program\Project Program\Participants.vb:line 39
PersonBindingSource.Add(PersonBindingSource.Item(LBsearch.SelectedIndex))
给出错误:
System.ArgumentException: Cannot add external objects to this list.
at System.Data.DataView.System.Collections.IList.Add(Object value)
at System.Windows.Forms.BindingSource.Add(Object value)
at Project_Program.Participants.btnremoveselect_Click(Object sender, EventArgs e) in E:\Documents\Visual Studio\Project Program\Project Program\Participants.vb:line 38
任何帮助将不胜感激.谢谢
Any help would be appreciated. Thanks
Private Sub btnaddselect_Click(sender As Object, e As EventArgs) Handles btnaddselect.Click
If LBsearch.Items.Count > 0 Then
MsgBox(LBsearch.Text)
' PersonBindingSource.Remove(PersonBindingSource.Item(LBsearch.SelectedIndex))
LBselect.Items.Add(LBsearch.Text)
PersonBindingSource.Remove(LBsearch.SelectedItem)
' filter()
End If
End Sub
Private Sub btnremoveselect_Click(sender As Object, e As EventArgs) Handles btnremoveselect.Click
If LBselect.Items.Count > 0 Then
Try
'PersonBindingSource.Add(PersonBindingSource.Item(LBsearch.SelectedIndex))
PersonBindingSource.Add(LBselect.SelectedItem)
MsgBox(LBselect.SelectedItem.ToString())
LBselect.Items.Remove(LBselect.SelectedItem)
Catch ex As Exception
TextBox1.Text = (ex.ToString)
End Try
'filter()
End If
End Sub
推荐答案
移动行的一个主要问题是,由于它们是DataRow
,因此它们在未绑定控件中不能很好地显示.如果您提取有用的名称(例如名称),则必须重新创建DataRow
,以将其返回到原始/绑定/源代码控件.
A major problem with moving rows is that since they are DataRow
s, they will not display well in the unbound control. If you pull out something useful like a name, you will have to recreate the DataRow
to return it to the original/bound/source control.
这是一个问题,因为现在它是新行,因此DataAdpter可能会将其再次添加到数据库中!避免这种情况的一种方法是克隆表.另外,如果/当您将它们移回时,它们将显示在列表的底部,而不是它们的原始位置.
This is a problem because, now it is a new row, so a DataAdpter might add it to the database again! One way to avoid that is to clone the table. Also, if/when you move them back, they will appear at the bottom of the list and not in their original position.
有一种比复制表数据并将任何内容移动到任何地方更好的方法.
There is a better way than duplicating the table data and moving anything anywhere.
由于可以使用简单的布尔值来表示被选择的行为,因此可以对其进行编码,以使Selected
控件显示在一个控件中,而未选中的控件则显示在另一个控件中.为此,需要一个新的Selected
列.如果可能,请使用您的SQL添加一个:
Since the act of being selected can be represented with a simple Boolean, it can be coded so that the Selected
ones show in one control, the unSelected ones in the other. For this, a new Selected
column is needed. If possible, add one using your SQL:
' MS Access syntax
Dim SQL = "SELECT a, b, c,..., False As Selected FROM tblFoo"
这将在您的数据表中创建所有初始化为False
的值的新列.您也可以手动添加列.
This will create the new column in your datatable with all the values initialized to False
. You can also add the column manually.
' form level vars
Private dvSource As DataView
Private dvDest As DataView
...
' set up:
' *** Add a column manually if you cant use SQL
dtSample.Columns.Add("Selected", GetType(Boolean))
' we need to loop and set the initial value for an added column
For Each r As DataRow In dtSample.Rows
r("Selected") = False
Next
' *** end of code for adding col manually
' when the column is added from SQL, you will need:
dtSample.Columns("Selected").ReadOnly = False
' create Source DV as Selected = False
dvSource = New DataView(dtSample,"Selected=False", "",
DataViewRowState.CurrentRows)
' create Dest DV as Selected = True
dvDest = New DataView(dtSample, "Selected=True", "",
DataViewRowState.CurrentRows)
' assign DS
lbSource.DataSource = dvSource
lbSource.DisplayMember = "Name"
lbSource.ValueMember = "Id"
lbDest.DataSource = dvDest
lbDest.DisplayMember = "Name"
lbDest.ValueMember = "Id"
然后在点击事件中:
' select
CType(lbSource.SelectedItem, DataRowView).Row("Selected") = True
' deselect:
CType(lbSource.SelectedItem, DataRowView).Row("Selected") = False
两个DataView
对象将在Selected
上反过滤.当您更改行的状态时,它会立即从一个状态中删除,并在另一行中显示,而实际上并未从任何表(或集合或控件)中添加/删除.如果将其移回源,它将显示在与以前相同的位置.
The two DataView
objects will filter on Selected
inversely. When you change the state of a row, it is instantly removed from one and appears in the other without actually being added/removed from any table (or collection or control). If you move it back to the Source it will appear in the same position as before.
在这种情况下,任何移动的项目的RowState
都将是Modified
,当然是Modified
(与移动到表的方法不同,它们将是新行(Added
),而不是).
In this case, the RowState
of any item moved will be Modified
, which of course it is (unlike the move-to-table approach where they would be new rows (Added
) which they are not).
如果没有5或6张图片,很难说明,但是这个想法:
It is hard to illustrate without 5 or 6 images, but the idea:
实际上,这是一种非常简单的方法,比一个实际移动行的调用更经济.使用DataView
s行/项看起来,它们将移至另一个表或控件,但它们并不需要,也不需要.
It is actually a pretty simple method and more economical than one invovling actually moving rows. Using DataView
s the rows/items look like they move to another table or control, but they do not, nor do they need to.
这篇关于将数据从数据绑定列表框移到未绑定列表框并返回VB.NET的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!