Toon posts:

[VB.NET / ADO.NET] Probleem met ComboBox

Pagina: 1
Acties:

Verwijderd

Topicstarter
Wanneer ik meerdere ComboBoxen probeer te koppelen aan een lookup table gaat er iets goed mis. Ik zal een voorbeeld geven van wat ik probeer te doen:


Visual Basic .NET:
1
2
3
4
5
6
Combo1.DataSource = EenDataSet.Tables("Valutas")
Combo1.DisplayMember = "Omschrijving"
Combo1.ValueMember = "Valuta ID"
Combo2.DataSource = EenDataSet.Tables("Valutas")
Combo2.DisplayMember = "Omschrijving"
Combo2.ValueMember = "Valuta ID"

Zo nu heb ik dus 2 ComboBoxen die beiden "Omschrijving" weergeven van een tabel "Valutas". Als ik nu het volgende probeer gebeurt er iets onverwachts:
Visual Basic .NET:
1
Combo1.SelectedIndex = 4

Nu wordt de SelectedIndex van Combo1 EN Combo2 veranderd in 4! Ik heb het idee dat de twee ComboBoxen een beetje samenwerken omdat ze dezelfde DataSource hebben. Nu is mijn vraag:

Hoe verander ik de SelectedIndex van Combo1 zonder de SelectedIndex van Combo2 impliciet te veranderen?

  • whoami
  • Registratie: December 2000
  • Laatst online: 18:49
Hmm, ik heb het net even getest en idd.... Vreemd. Best stom eigenlijk.

Ik heb eens op internet gezocht, en kwam op deze link:
http://www.dotnet247.com/247reference/msgs/24/122660.aspx

Echter, ik vind het maar een zwakke workaround. Per combobox een andere datatable gebruiken in je dataset is niet echt een mooie of efficiente oplossing te noemen.

Misschien kan je eens kijken naar die andere tip, die CurrencyManager. Ik heb er zelf geen ervaring mee, maar ga dat ook eens van dichterbij bekijken.

https://fgheysels.github.io/


  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 20-08 11:40

gorgi_19

Kruimeltjes zijn weer op :9

JE kan eens kijken naar de clone method van de dataset. Ik heb nu even geen voorbeeld bij de hand (en ff geen tijd), maar volgens mij moet dit een oplossing zijn..

Ik zal straks ff kijken of ik wat relevante stukken kan quoten.
The idea of cloning a class instance (making an exact copy) is not a designed-in feature of C#, but nothing actually stops you from carrying out such a copy yourself. The only place the Clone method appears in C# is in ADO Dataset manipulation. You can create a DataSet as a result of a dataabase query and move through it a row at a time. If for some reason you need to keep references to two places in this DataSet, you would need two current rows. The simples way to handle this in C# is to clone the dataset.

C#:
1
2
DataSet cloneSet;
closeSet = myDataSet.Clone;

Now this approach does not generate two copies of the data. It just generates two sets of row pointers to use to move through the records independently of each other. Any change you make in one clone of the DataSet is immediately reflected in the other, bevayse there is in fact only one data table.
Bovenstaand stuk werd gebruikt als introductie op het prototype design pattern.

[ Voor 69% gewijzigd door gorgi_19 op 18-03-2003 16:17 ]

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • whoami
  • Registratie: December 2000
  • Laatst online: 18:49
Ik vind het toch wel gek waarom MS voor deze aanpak gekozen heeft...

Ziet er iemand misschien voordelen in deze manier van werken? Hoe is dit 'intern' te verklaren?

https://fgheysels.github.io/


  • henkleerssen
  • Registratie: December 2000
  • Niet online

henkleerssen

Your life is as you narrate it

whoami schreef op 18 March 2003 @ 16:15:
Ik vind het toch wel gek waarom MS voor deze aanpak gekozen heeft...

Ziet er iemand misschien voordelen in deze manier van werken? Hoe is dit 'intern' te verklaren?
Dat databinden in combinatie met vb.net.. gaat niet echt altijd lekker zie ook [rml][ vb.net] gebruik van delegates[/rml]

Ook al is het voor ms een uitgemaakte zaak (iedereen moet naar deze manier van db proggen), snap ik toch niet waarom het een en ander toch zo moeilijk moet worden...
ADO zonder databinden in combinatie met vb.net of 6 gaat toch echt gewoon het makkelijkst .. is mijn mening...

  • whoami
  • Registratie: December 2000
  • Laatst online: 18:49
henkleerssen schreef op 18 March 2003 @ 16:21:
[...]

Dat databinden in combinatie met vb.net.. gaat niet echt altijd lekker zie ook [rml][ vb.net] gebruik van delegates[/rml]
Ik geloof dat deze 2 topics totaal los van elkaar staan. :)
Ook al is het voor ms een uitgemaakte zaak (iedereen moet naar deze manier van db proggen), snap ik toch niet waarom het een en ander toch zo moeilijk moet worden...
ADO zonder databinden in combinatie met vb.net of 6 gaat toch echt gewoon het makkelijkst .. is mijn mening...


Tja, gewoon je dataset of datareader overlopen en zelf ieder item adden aan de combobox gaat natuurlijk ook. Het is maar wat je verkiest.
Afaik gaat 'databinden' sneller dan handmatig alle items te adden.

https://fgheysels.github.io/


  • henkleerssen
  • Registratie: December 2000
  • Niet online

henkleerssen

Your life is as you narrate it

whoami schreef op 18 maart 2003 @ 16:23:

[...]

Ik geloof dat deze 2 topics totaal los van elkaar staan. :)


[...]
In dat andere topic hadden we het ook ff over databinden geloof ik.. maar dan in combi met delegates...
Dus om nou te zeggen dat ze los van elkaar staan...

  • whoami
  • Registratie: December 2000
  • Laatst online: 18:49
henkleerssen schreef op 18 March 2003 @ 16:33:
[...]

In dat andere topic hadden we het ook ff over databinden geloof ik.. maar dan in combi met delegates...
Dus om nou te zeggen dat ze los van elkaar staan...


't Is niet omdat in alletwee de topics hetzelfde woordje naar voor komt, dat die topics met elkaar te maken hebben.
Back on topic dan maar.

https://fgheysels.github.io/


Verwijderd

Topicstarter
In reactie op de 'elegante' oplossing die gorgi_19 voorstelde heb ik het volgende geprobeerd:

Visual Basic .NET:
1
2
3
4
5
6
Combo1.DataSource = EenDataSet.Tables("Valutas")
Combo1.DisplayMember = "Omschrijving"
Combo1.ValueMember = "Valuta ID"
Combo2.DataSource = EenDataSet.Clone.Tables("Valutas")
Combo2.DisplayMember = "Omschrijving"
Combo2.ValueMember = "Valuta ID"

Het bovenstaande resulteert in een lege ComboBox (Combo2)

Ik probeer vervolgens het volgende:
Visual Basic .NET:
1
2
3
4
5
6
Combo1.DataSource = EenDataSet.Tables("Valutas")
Combo1.DisplayMember = "Omschrijving"
Combo1.ValueMember = "Valuta ID"
Combo2.DataSource = EenDataSet.Tables("Valutas").Clone
Combo2.DisplayMember = "Omschrijving"
Combo2.ValueMember = "Valuta ID"

Hier blijkt dat alleen de tabel clonen ook geen oplossing is, dit resulteert wederom in een lege ComboBox (Combo2).

Nu zal ik dus de ComboBoxen handmatig moeten gaan vullen met "Omschrijving" uit de tabel "Valutas" en later hierbij "Valuta ID" opzoeken. Alleen hoop ik dat de kolom "Omschrijving" uniek is, anders zit ik dus nog steeds met een probleem :'(

  • cablepokerface
  • Registratie: Januari 2001
  • Laatst online: 29-01 16:53
Je bent niet verplicht om databinding te gebruiken ... het is zlechts een gemakkelijke manier om een 2-way communicatie met de DB te hebben. (Als je dus het item wijzigt wordt dit dus ook weer opgeslagen in de DB).

Maak eens een expliciete clone van de dataset ...

Zo ongeveer:

Dim MyDS As DataSet = New DataSet
MyDS = EenDataSet.Clone

Combo1.DataSource = EenDataSet.Tables("Valutas")
Combo1.DisplayMember = "Omschrijving"
Combo1.ValueMember = "Valuta ID"
Combo2.DataSource = MyDS.Tables("Valutas")
Combo2.DisplayMember = "Omschrijving"
Combo2.ValueMember = "Valuta ID"

[ Voor 24% gewijzigd door cablepokerface op 18-03-2003 16:57 ]


  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 20-08 11:40

gorgi_19

Kruimeltjes zijn weer op :9

* gorgi_19 gaat ook ff uitproberen.. Zou ook best de copy ipv clone kunnen zijn.. :X stom boek ook..

Was idd de copy method.. Clone 'kopieert' de structuur zonder data, Copy met de data

Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
        Dim ds As New DataSet()
        Dim dt As New DataTable()
        dt.Columns.Add(New DataColumn("blaat", GetType(String())))
        dt.Columns.Add(New DataColumn("blaat2", GetType(String())))

        Dim dr As DataRow = dt.NewRow
        dr("blaat") = "lorem"
        dr("blaat2") = "lorem2"
        dt.Rows.Add(dr)

        Dim dr2 As DataRow = dt.NewRow
        dr2("blaat") = "loremNon"
        dr2("blaat2") = "loremNon2"
        dt.Rows.Add(dr2)

        ds.Tables.Add(dt)

        Me.ComboBox1 = New System.Windows.Forms.ComboBox()
        Me.ComboBox2 = New System.Windows.Forms.ComboBox()
        Me.SuspendLayout()
        '
        'ComboBox1
        '
        Me.ComboBox1.Location = New System.Drawing.Point(72, 48)
        Me.ComboBox1.Name = "ComboBox1"
        Me.ComboBox1.Size = New System.Drawing.Size(121, 21)
        Me.ComboBox1.TabIndex = 0
        Me.ComboBox1.Text = "ComboBox1"
        Me.ComboBox1.DataSource = ds.Tables(0)
        Me.ComboBox1.DisplayMember = "blaat"
        Me.ComboBox1.ValueMember = "blaat2"
        '
        'ComboBox2
        '
        Me.ComboBox2.Location = New System.Drawing.Point(72, 88)
        Me.ComboBox2.Name = "ComboBox2"
        Me.ComboBox2.Size = New System.Drawing.Size(121, 21)
        Me.ComboBox2.TabIndex = 1
        Me.ComboBox2.Text = "ComboBox2"
        Me.ComboBox2.DataSource = ds.Tables(0).Copy
        Me.ComboBox2.DisplayMember = "blaat"
        Me.ComboBox2.ValueMember = "blaat2"

Sorry whoami, je had gelijk... O-)

[ Voor 104% gewijzigd door gorgi_19 op 18-03-2003 17:54 ]

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • whoami
  • Registratie: December 2000
  • Laatst online: 18:49
Eigenlijk blijf ik het een rare manier vinden....

Het zou toch de Combobox moeten zijn die voor de representatie van de data zorgt, en hij zou zijn datasource daar toch helemaal niet mogen bij betrekken.
De combobox zou toch wel in staat moten zijn om bv. het 3de item te tonen zonder dat hij daarvoor het 'current record' oid in de dataset moet gaan wijzigen.

https://fgheysels.github.io/


Verwijderd

Topicstarter
gorgi_19 het werkt :D. Dank aan iedereen die geholpen heeft. Nu rest alleen nog de vraag wat M$ motiveert op deze manier met databinding om te gaan.

  • whoami
  • Registratie: December 2000
  • Laatst online: 18:49
Verwijderd schreef op 19 maart 2003 @ 09:50:
gorgi_19 het werkt :D. Dank aan iedereen die geholpen heeft. Nu rest alleen nog de vraag wat M$ motiveert op deze manier met databinding om te gaan.


Vraag ik me ook af....

Ik zie daar niet zo 123 de voordelen van in. Misschien iemand die eens deze situatie kan 'verhelderen'?

https://fgheysels.github.io/


  • whoami
  • Registratie: December 2000
  • Laatst online: 18:49
Even kicken.
Misschien weet iemand er nog wat zinnigs op te zeggen.

https://fgheysels.github.io/


Verwijderd

Topicstarter
OK whoami en anderen, ik heb gevonden hoe het volgens M$ moet:

code:
1
2
3
4
5
6
7
8
9
Dim View1 As New DataView(EenDataSet.Tables("Valutas"))
Combo1.DataSource = View1
Combo1.DisplayMember = "Omschrijving"
Combo1.ValueMember = "Valuta ID"

Dim View2 As New DataView(EenDataSet.Tables("Valutas"))
Combo2.DataSource = View2
Combo2.DisplayMember = "Omschrijving"
Combo2.ValueMember = "Valuta ID"


Zoals je ziet heeft M$ een heel andere 'kijk' op data (binding) ;). Zo'n DataView houdt een eigen CurrentRow, RowFilter en nog veel meer bij. Eigelijk best handig. Elke Table heeft een DefaultView. Het probleem was dus dat de ComboBoxen 1 en 2 de zelfde Table als DataSource en dus de zelfde DataView en CurrentRow deelden!

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Wat doet mijn nick in de topictitel?

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


Verwijderd

Misschien ben ik een beetje laat met reageren,
maar ik vind het eingelijk best normaal dat als je 2x dezelfde datatable gebruikt, dat alle componenten die eraan vast zitten dezelfde "active" regel tonen.

Als je met 10 man in één boek zit te lezen.
En 1 iemand draait de bladzijde om, dan moet de rest daar ook naar kijken.

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Dit hoeft niet hetzelfde te zijn. Het is in dit geval maar net waar je de 'active row' bijhoudt. TS verwacht, redelijkerwijs, dat de combobox dat doet, zodat je meerdere views op dezelfde data kunt bouwen. Dit blijkt dus niet het geval te zijn, en er is kennelijk een 'active row' in de datatable. Werkelijk onbegrijpelijk dat die proggers van Microsoft dit zo hebben kunnen verzinnen. De enige reden die ik ervoor kan verzinnen is dat met 1 active row in de table, je sequentieel rows moet wijzigen en niet multithreaded. Echter voor een read-only gebruik boeit dat dus niet.

Als workaround kan de TS 2 dataviews creeeren van de table en die aan de comboboxen binden (of 1 table en 1 view)

[ Voor 3% gewijzigd door EfBe op 03-04-2003 11:05 ]

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


Verwijderd

Nou in Delphi als je bijv meerde componenten op een datasource (-> query) zet,
heb je ook maar 1 actief record.

Wat als voordeel kan hebben dat je een grid hebt, met detail controls er langs de de data AUTOMATISCH krijgen, om dat het actieve record veranderd.

En ander moet je je control niet BINDEN, dat betekend je zit vast aan je data, of het nu een datatable of iets anders is.
Maak dan een fuctie die dat ding van uit een datatable vult.

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Dat is inderdaad een voordeel waar ik niet aan gedacht heb. ff 'prutsers' veranderen in 'proggers' :D. In dat opzicht is het weer een voordeel dat er per binding 1 actief record is. Echter, dit zou optioneel moeten zijn. Nu moet je 2 aparte extra objects maken, en met veel rows kan dat dan weer belastend zijn terwijl dat helemaal niet hoeft.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • whoami
  • Registratie: December 2000
  • Laatst online: 18:49
Hmm.... Ik denk hier aan het observer design pattern.

De DataTable is het subject en de dataview's zijn de observers van dat subject; ipv de control die de observer is.
Goed dat het op die manier (met die dataview's) op te lossen is. Je moet het natuurlijk weten, anders ben je voor hetzelfde geld bezig met -in dit geval- per combobox een nieuwe datatable te maken (of te clonen).

https://fgheysels.github.io/

Pagina: 1