| |
VB.NET - Ein- und UmsteigerBindingSource.Filter zu gross? | | | Autor: ProXy | Datum: 10.09.08 08:46 |
| Guten Morgen zusammen,
ich habe eine DataGridView, welches als DataSource eine BindingSource verwendet. In der BindingSource befinden sich rund 9000 Datensätze. Wenn man im DataGridView eine grosse Anzahl Datensätze auswählt und die Leertaste drückt, sollen die ausgewählten Datensätze in ein anderes DataGridView übernommen werden. Das Problem ist nun der Filter des BindingSource. Da der Anwender 2000 Datensätze selektieren kann, muss mein Filter 2000 Datensätze einzeln filtern (x <> 1 AND x <> 2 AND x <> 3... AND x <> 2000).
Nun erhalte ich eine StackOverflowException sobald der Filter angewendet wird. Hat jemand eine Idee, wie ich entweder einen schlaueren Filter setzen kann, oder aber einen ganz anderes Ansatz verwenden kann? Ich könnte auch ein ungebundenes DataGridView verwenden, wenn ich darüber aber schleifen muss, wird das wohl auch nicht sehr performant!
Gruss,
Stefan | |
Re: BindingSource.Filter zu gross? | | | Autor: ProXy | Datum: 10.09.08 13:21 |
| Ich lese aus einer SQL-Datenbank eine Tabelle mit fast 10.000 Datensätzen aus und fülle damit ein DataGridView. Nun kann der Anwender eine oder mehrere Zeilen im DataGridView auswählen und diese bestimmten Gruppen zuordnen. Jede Gruppe hat ein Tab und ein eigenes DataGridView.
Ich könnte die DataGridViews auch ungebunden erstellen, dann aber müsste ich diese immer durchschleifen, was SEHR langsam ist. Mit einem BindingSource als DataSource kann ich einfach die Zeilen herausfiltern, die schon zugeordnet wurden. Ich habe schon mehrere Ansätze verfolgt (datatable.select, ungebunden und die Zeilen direkt aus dem Datagridview nehmen, etc.) aber alles funktioniert entweder sehr langsam oder gar nicht.
Hast du evtl. eine Idee, wie ich die Datensätze, die bereits zugeordnet wurden aus dem Grid bekomme? | |
Re: BindingSource.Filter zu gross? | | | Autor: ProXy | Datum: 10.09.08 14:01 |
| Die Zuordnungen werden abgespeichert. Das Programm dient lediglich dazu, dass einer unserer Kunden eine Gruppierung für einen bevorstehenden Datenimport selber festlegen kann..
PS: Wo lege ich das neue Feld an? In der Datatable, die als DataSource des BindingManagers definiert ist?
Beitrag wurde zuletzt am 10.09.08 um 14:07:56 editiert. | |
Re: BindingSource.Filter zu gross? | | | Autor: ProXy | Datum: 10.09.08 14:30 |
| Gut, danke, das habe ich bereits erledigt. Das letzte Problem das mir noch etwas zu knabbern gibt: Wie ändere ich den Wert der Spalte in meiner DataTable, wenn der Anwender auf die Zeile im Grid klickt? Wo kann ich praktisch die Zuordnung der DataGridViewRow zu DataRow herausfinden? | |
Re: BindingSource.Filter zu gross? | | | Autor: ProXy | Datum: 10.09.08 14:46 |
| Ohje, ich hab current schon gesehen, allerdings "DataGridViewRow" statt "DataRowView" gelesen und bin davon ausgegangen, dass das nicht stimmen kann. Ich danke dir vielmals für die Hilfe! | |
Re: BindingSource.Filter zu gross? | | | Autor: ProXy | Datum: 10.09.08 16:16 |
| Ich dachte eigentlich nun über den Berg zu sein, da es mit einem BindingSource wunderbar funktioniert hat, sobald aber ein zweites dazukommt, stimmt nichts mehr.
Die DataTable mit den Werten aus der Datenbank ist global. Wenn ich diese DataTable nun bei zwei verschiedenen BindingSources als DataSource verwende (bindingsource.datasource = datatable), dann scheint es so als würde der Filter der einen BindingSource den anderen überschreiben, denn plötzlich wird das Grid leer. Verwende ich stattdessen bindingsource.datasource = datatable.defaultview.totable(), dann sind beide scheinbar unabhängig voneinander.
Klicke ich nun auf eine Zeile im DataGridView mit allen Datensätzen, dann verschwindet diese Zeile auch aus dem DataGridView, es taucht aber nicht im DataGridView des entsprechenden Tabs auf.
Ich habe mal den nötigsten Code extrahiert, evtl. sieht jemand darin den Fehler:
Private dtData As DataTable
Private Sub Main_Load(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles MyBase.Load
Dim bsArtikel As BindingSource
dtData = sqlDataTable("SELECT AR_Nummer, AR_Bezeichnung FROM Artikel")
dtData.Columns.Add("AR_Gruppe", GetType(String))
bsArtikel = New BindingSource
bsArtikel.DataSource = dtData.DefaultView.ToTable
bsArtikel.Filter = getFilter()
DataGridView1.DataSource = bsArtikel
End Sub
'Nach dem Load ist das DataGridView1 komplett befüllt, da der Filter auf
' "AR_Nummer is null" gesetzt ist. Soweit also noch richtig.
Private Sub DataGridView1_MouseDoubleClick(ByVal sender As Object, ByVal e _
As System.Windows.Forms.MouseEventArgs) Handles _
DataGridView1.MouseDoubleClick
Dim info As DataGridView.HitTestInfo
Dim bs As BindingSource
Dim drvRow As DataRowView
If e.Button = Windows.Forms.MouseButtons.Left Then
If TabControl1.SelectedTab Is Nothing Then
MessageBox.Show("Bitte legen zu zunächst einen Tab an!", "Tab" & _
"anlegen", MessageBoxButtons.OK, MessageBoxIcon.Information)
Exit Sub
End If
info = DataGridView1.HitTest(e.X, e.Y)
If info.RowIndex >= 0 Then
bs = CType(DataGridView1.DataSource, BindingSource)
DataGridView1.CurrentCell = DataGridView1.Rows( _
info.RowIndex).Cells(0)
drvRow = CType(bs.Current, DataRowView)
drvRow.Item("AR_Gruppe") = TabControl1.SelectedTab.Text
bs.EndEdit()
End If
End If
'Nach bs.EndEdit ist die Zeile aus dem DataGridView verschwunden, taucht aber
' im anderen Grid nicht auf! Zur Kontrolle habe ich die DataTable dann mal
' durchgeschliffen:
For Each dtrow As DataRow In dtData.Rows
If Not dtrow.Item("AR_Gruppe") Is DBNull.Value Then
MsgBox(dtrow.Item("AR_Gruppe"))
End If
Next
'Es erscheint nie eine MessageBox, einer der Werte muss doch nun aber geändert
' worden sein?
End Sub Sieht hier jemand, wo der Fehler liegen könnte? Der Filter der anderen BindingSources ist richtig, dies habe ich bereits kontrolliert. | |
Re: BindingSource.Filter zu gross? | | | Autor: ProXy | Datum: 10.09.08 16:51 |
| Ich habe ein Testprojekt mit einer globalen DataTable gemacht:
BindingSource1.DataSource = dt
BindingSource1.Filter = "Column1='1'"
BindingSource2.DataSource = dt
BindingSource2.Filter = "Column1='2'"
DataGridView1.DataSource = BindingSource1
DataGridView2.DataSource = BindingSource2 Wenn ich das so mache, habe ich zwei getrennte BindingSources, allerdings steht in beiden Grids das gleiche, nämlich das, was der Filter der letzen BindingSource zurückgibt... | |
Re: BindingSource.Filter zu gross? | | | Autor: DaveS (Moderator) | Datum: 10.09.08 18:46 |
| Also, dein Beitrag hat mich auf ein seltsames Verhalten von BindingSource zum ersten Mal aufmerksam gemacht. Wenn ein BS so angelegt wird, nur mit Tabelle, stimmt was du sagst. Die zwei Bs teilen sich ein DataView, und weil DataView das Objekt ist was eigentlich filtert und sortiert machen die zwei Bs gemeinsame Sache.
Wenn dagegen ein DataSet verwendet wird (was ich üblicherweise mache, wenn ich DataBinding mit Ado.Net verwende), dann muss man entweder im Kontsruktor oder als Property-Zuweisung ein DataMember angeben (die Tabelle im DataSet). Dann funktionieren die Bs wie ich erklärt habe.
Das finde ich äusserst seltsam. Es kann eigentlich nicht der Sinn vom BindingSource sein, quasi als alternative Pfade auf eine Liste (DataView) zuzugreifen, weil es denn gar keinen Sinn macht zwei Bs überhaupt zu haben. Auf jeden Fall, das ist die Situation.
Mit DataSet legt man ein BindingSource so an
Dim bs As New BindingSource(ds, "Tabelle") ________
Alle Angaben ohne Gewähr. Keine Haftung für Vorschläge, Tipps oder sonstige Hilfe, falls es schiefgeht, nur Zeit verschwendet oder man sonst nicht zufrieden ist | |
Re: BindingSource.Filter zu gross? | | | Autor: FZelle (Moderator) | Datum: 10.09.08 19:43 |
| Ist aber so, da BindingSource lediglich das Interface IBindingListView benutzt.
Ein DataSet erzeugt dann jeweils einen eigenen DataView für jede BindingSource,
eine DataTable macht keine anstalten sich zu "teilen". | |
Re: BindingSource.Filter zu gross? | | | Autor: DaveS (Moderator) | Datum: 10.09.08 20:05 |
| BindingSource implementiert IBindingListView. Und zwar ob man so oder so ein BindingSource anlegt. Ich sehe nicht warum das dieses Verhalten erklären soll. Lediglich wird in beiden Fällen mit genau einer Tabelle gebunden. Ohne BindingSource spielt beim DataBinding .BindingContext eine wichtige Rolle, und sorgt dafür, dass unterschiedliche Bindings die gleiche Liste verwenden, was notwendig ist, um dass alle Bindings synchron laufen. Allerdings will man das nicht immer. Z.B. zwei Combos sollen bestimmte Spalten aus einer Liste darstellen, ohne, dass eine Auswahl in einer Combo die andere beeinflüsst. Da hat man BindingSource als Lösung, wie ich oft genug vorgeschlagen habe. Dass unter Umständen BindingSource ganz anders agiert finde ich schon sehr fragwürdig. Ich kann mir nicht vorstellen, dass irgendeine Absicht dahinter steht.
________
Alle Angaben ohne Gewähr. Keine Haftung für Vorschläge, Tipps oder sonstige Hilfe, falls es schiefgeht, nur Zeit verschwendet oder man sonst nicht zufrieden ist | |
| Sie sind nicht angemeldet! Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.
Einloggen | Neu registrieren |
|
|
Neu! sevCoolbar 3.0
Professionelle Toolbars im modernen Design!
Mit sevCoolbar erstellen Sie in wenigen Minuten ansprechende und moderne Toolbars und passen diese optimal an das Layout Ihrer Anwendung an (inkl. große Symbolbibliothek) - für VB und MS-Access Weitere InfosTipp des Monats Access-Tools Vol.1
Über 400 MByte Inhalt
Mehr als 250 Access-Beispiele, 25 Add-Ins und ActiveX-Komponenten, 16 VB-Projekt inkl. Source, mehr als 320 Tipps & Tricks für Access und VB
Nur 24,95 EURWeitere Infos
|