2016-04-01 9 views
1

Also habe ich über Browsing und es gibt eine Menge Erklärungen, wie Sie Daten von Listbox zu Listbox verschieben. Ich habe eine Listbox an eine Quelle von meinem SQL Server gebunden und eine weitere ungebunden. Mein Ziel ist es, die Daten von der ersten (LBsearch) auf die zweite (LBselect) und zurück zu verschieben. Ich habe gesehen, dass Leute sagen, verwenden Sie LBselect.Items.Add(LBsearch.SelectedItem), aber es gibt keine Daten zurück und zeigt stattdessen System.Data.DataRowView. Ich habe viele verschiedene Suffixe ausprobiert und alle zeigen dies abgesehen von LBsearch.text. Dann, um die Daten von der ersten zu entfernen, habe ich die Datenquelle (PersonBindingSource) mit PersonBindingSource.Remove(LBsearch.SelectedItem) entfernt, aber mein Problem ist das Hinzufügen der Daten wieder zurück.Verschieben von Daten von Databound Listbox zu Unbound Listbox und Zurück VB.NET

PersonBindingSource.Add(LBselect.SelectedItem) gibt einen Fehler:

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 

Jede mögliche Hilfe würde geschätzt:

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)) einen Fehler gibt. Dank


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

Der eine, der gebunden ist, hat db-Zeilen durch ein DataView "zugeordnet". Wenn Sie ValueMember festgelegt haben, gibt Ihnen der SelectedValue im ValueChanged-Ereignis diese Zeile. Ich weiß nicht, was du auf die andere LB setzen willst; Wenn Sie die Zeile hinzufügen möchten, legen Sie die Eigenschaften DisplayMember und ValueNenber fest, oder zeigen Sie den Text an, holen Sie ihn aus dem SelectedValue - umwandeln Sie ihn in eine DataRow und erhalten Sie das gewünschte Feld – Plutonix

+0

Mögliches Duplikat von [Wie man ein mobiles Gerät erkennt Javascript?] (http://stackoverflow.com/questions/6666907/how-to-detect-a-mobile-device-with-javascript) –

Antwort

1

Ein großes Problem Reihen mit beweglichem ist, dass da sie DataRow s sind, werden sie in der ungebundenen Kontrolle nicht gut an. Wenn Sie etwas Nützliches wie einen Namen herausziehen, müssen Sie das DataRow neu erstellen, um es an das ursprüngliche/gebundene/Quellcode-Steuerelement zurückzugeben.

Dies ist ein Problem, denn jetzt ist es eine neue Zeile, also könnte ein DataAdapter es wieder zur Datenbank hinzufügen! Eine Möglichkeit, dies zu vermeiden, ist das Klonen der Tabelle. Wenn Sie sie zurück bewegen, erscheinen sie am Ende der Liste und nicht an der ursprünglichen Position.

Es gibt einen besseren Weg, als die Tabellendaten zu duplizieren und alles irgendwohin zu verschieben.

Da der Vorgang der Auswahl mit einem einfachen booleschen Wert dargestellt werden kann, kann er so codiert werden, dass die Selected in einem Steuerelement, die nicht ausgewählten im anderen Steuerelement angezeigt werden. Dazu wird eine neue Spalte Selected benötigt. Wenn möglich, fügen Sie eine SQL-Verwendung:

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

Dies wird die neue Spalte in der Datentabelle mit allen Werten zu False initialisiert erstellen. Sie können die Spalte auch manuell hinzufügen.

' 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" 

Dann in den Click-Ereignisse:

' select 
CType(lbSource.SelectedItem, DataRowView).Row("Selected") = True 

' deselect: 
CType(lbSource.SelectedItem, DataRowView).Row("Selected") = False 

Die beiden DataView Objekte auf Selected invers filtert. Wenn Sie den Status einer Zeile ändern, wird sie sofort aus der einen Zeile entfernt und in der anderen Zeile angezeigt, ohne dass sie tatsächlich aus einer Tabelle (oder Sammlung oder Steuerelement) hinzugefügt/entfernt wird. Wenn Sie es zurück zur Quelle bewegen, erscheint es in der gleichen Position wie vor.

In diesem Fall bewegt die RowState eines Elements Modified sein wird, was es natürlich (im Gegensatz zu den Move-to-Tabelle Ansatz, in dem sie neue Zeilen sein würde (Added), die sie nicht sind) ist.

Es ist schwer, ohne 5 oder 6 Bilder zu veranschaulichen, aber die Idee:

enter image description here

Es ist eigentlich ein ziemlich einfaches Verfahren und wirtschaftlicher als ein tatsächlich bewegende Reihen invovling. Mit DataView s die Zeilen/Elemente aussehen wie sie bewegen sich zu einer anderen Tabelle oder Kontrolle, aber sie tun nicht, noch müssen sie.

+0

Danke für Ihre Eingabe Plutonix! Ich habe versucht, das zu tun, was Sie geschrieben haben, und jetzt zeigen beide Listenfelder ein Leerzeichen. Kannst du einen Blick darauf werfen und sehen, ob du meinen Fehler erkennen kannst? http://pastebin.com/Qc8hV0eZ –

+0

Ich weiß nicht, was einige dieser Dinge sind, aber unter der Annahme, 'All.Person 'ist eine legitime Datentabelle, warum würden Sie" CollegeID "als DisplayMember verwenden? Hat die zugrunde liegende Tabelle sogar diese Spalte? – Plutonix

+0

Die 2 Tabellen, die ich verwende, dienen zur Auswahl von Studenten-ID-Nummern, die zu einer Buchungsreferenz hinzugefügt werden. In SQL hat es CollegeID. PersonID ist der eindeutige Schlüssel, den die Datenbank verwendet. 'All.Person' ist die Datenquelle. –