2016-04-01 73 views
1

因此,我一直在瀏覽有關如何將數據從列表框移動到列表框的說明。 我有一個列表框綁定到我的SQL服務器和另一個未綁定的源。我的目標是將數據從第一個(LBsearch)移到第二個(LBselect)並返回。我看到有人說使用 LBselect.Items.Add(LBsearch.SelectedItem)但是它不返回數據,而是顯示System.Data.DataRowView。我已經嘗試了許多不同的後綴,並且都從LBsearch.text中分辨出來。然後從第一個刪除數據我一直在刪除數據綁定來源(PersonBindingSource)PersonBindingSource.Remove(LBsearch.SelectedItem)但我的問題是再次添加數據。將數據從數據綁定列表框移動到未綁定列表框並返回VB.NET

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 

任何幫助,將不勝感激。由於


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 
+0

被綁定的那個數據庫行通過DataView「映射」到它。如果您設置了ValueMember,則在ValueChanged事件中,SelectedValue會爲您提供該行。我不知道你想要放在另一個LB上;如果要添加行,請設置DisplayMember和ValueNenber屬性,或者顯示文本,從SelectedValue獲取 - 將其轉換爲DataRow並獲取所需的任何字段 – Plutonix

+0

可能的重複[如何檢測移動設備javascript?](http://stackoverflow.com/questions/6666907/how-to-detect-a-mobile-device-with-javascript) –

回答

1

與移動行的一個主要問題是,由於它們是DataRow S,他們將不會在綁定控件顯示效果出色。如果您拔出一些有用的名稱,則必須重新創建DataRow以將其返回到原始/綁定/源代碼控制。

這是一個問題,因爲現在它是一個新行,因此DataAdpter可能會再次將其添加到數據庫!避免這種情況的一種方法是克隆表。另外,如果/當您將它們移回時,它們將出現在列表的底部,而不是原來的位置。

有比複製表格數據和任何地方移動任何東西更好的方法。

由於被選中的行爲可以用一個簡單的布爾表示,因此可以對其進行編碼,以使Selected個人在一個控件中顯示,而在另一個控件中顯示未選中的人。爲此,需要新的Selected列。如果可能的話,使用SQL添加一個:

' MS Access syntax 
Dim SQL = "SELECT a, b, c,..., False As Selected FROM tblFoo" 

這將初始化爲False的所有值創建數據表的新列。您也可以手動添加列。

' 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成反比。當你改變一行的狀態時,它會立即從一個表中刪除,並出現在另一個表中,而不會實際添加/從任何表(或集合或控件)中刪除。如果您將其移回源,它將出現在與之前相同的位置中。

在這種情況下,任何項目的RowState移動將Modified,這當然是(不像移動到餐桌的方法,他們將是新行(Added),他們都沒有)。

很難舉例說明而不是5倍或6的圖像,但這個想法:

enter image description here

它實際上是一個非常簡單的方法和一種以上invovling實際移動行更經濟。使用DataView s行/項目看起來像他們移動到另一個表或控件,但他們不,也不需要。

+0

感謝您輸入Plutonix!我試着做你寫的東西,現在兩個ListBox都顯示一個空白。你可以看一下,看看你能否發現我的錯誤? http://pastebin.com/Qc8hV0eZ –

+0

我不知道這些東西中有些是什麼,但假設'All.Person'是一個合法的數據表,爲什麼要使用「CollegeID」作爲DisplayMember?底層表甚至有那一列嗎? – Plutonix

+0

我使用的兩個表格是選擇學生ID號碼以添加到預訂參考。在SQL中它有CollegeID。 PersonID是數據庫使用的唯一鍵。 'All.Person'是數據源。 –