webForumDet fria alternativet

Databinda XML eller DataSet till ListBox

.NETur .NET

7 svar · 491 visningar · startad av PDahlen

Medlem sedan apr. 2004778 inlägg
Frågan#1

Jag har börjat pula med min första Winforms applikation i VB.NET och försöker databinda XML till en ListBox.
XML-filen läser jag in från en URL med XmlTextReader.

XML

<xml version="1.0">
  <dellist>
    <delivery>
      <id>140</id>
      <description>Tisdag: Bil 2</description>
      <deliverydate>2004-08-10</deliverydate>
    </delivery>
    <delivery>
      <id>139</id>
      <description>Tisdag: Bil 1</description>
      <deliverydate>2004-08-10</deliverydate>
    </delivery>
    <delivery>
      <id>142</id>
      <description>Onsdag: Bil 2</description>
      <deliverydate>2004-08-11</deliverydate>
    </delivery>
    <delivery>
      <id>141</id>
      <description>Onsdag: Bil 1</description>
      <deliverydate>2004-08-11</deliverydate>
    </delivery>
  </dellist>
</xml>

VB.NET kod

    Private Const localURL As String = "http://minsajt/min.xml"

        Dim myXmlURLReader As XmlTextReader

        myXmlURLReader = New XmlTextReader(localURL)

        Dim myDataSet As DataSet = New DataSet
        myDataSet.ReadXml(myXmlURLReader)
        Me.Label2.Text &= myDataSet.GetXml.ToString & vbCrLf
        Me.Label2.Text &= "Processing ..." & vbCrLf & vbCrLf
        Me.ListBox1.DataSource = myDataSet
        Me.ListBox1.ValueMember = "id"
        Me.ListBox1.DisplayMember = "description"

Försöker alltså databinda till en ListBox. Skriver även ut mitt DataSet som XML i Label2 för att kolla att allt ser OK ut och det gör det.

Om jag sätter min XmlTextReader som DataSource får jag:
"Complex DataBinding accepts as a data source either an IList or an IListSource"

Så istället läser jag in min XML till ett DataSet, men då får jag:
"Could not bind the new display member. Parameter name: newDisplayMember"

Om jag struntar i
Me.ListBox1.ValueMember = "id"
så funkar det utan felmeddelande, men det som visas i ListBoxen är

System.Data.DataViewManagerListItemTypeDescriptor

istället för värdet som finns i "description"
Det jag behöver är alltså att "description" ska visas och id-numret skall vara värdet som jag ska använda när man gjort ett val.

Några förslag?

En annan sak är att jag ser i min Task Manager att appen drar iväg med nästan 16MB. Verkar inte det mycket för en liten app?

Medlem sedan apr. 2004778 inlägg
#2

Löste problemet.
Det skulle vara:
"delivery.id" och "delivery.description", eller så tar jag bort delivery som item.

Medlem sedan nov. 2003569 inlägg
#3

Får man fråga varför du använder en XmlTextReader?
DataSet´s har en inbyggd xml läsare

		DataSet mydataset=new DataSet();
		mydataset.ReadXml("http://blog.johnkerry.com/index.xml");
		dataGrid1.DataSource=mydataset;

Förresten, testa denna kod och märk hur fint DataSets och Datagrids hanterar relationer helt automatiskt.

Medlem sedan apr. 2004778 inlägg
#4

Använde XmlTextReader för det var det som visades i exemplet jag kollade på. ;)

Helst skippar jag DataSettet helt och binder XmlTextReadern direkt till LixtBoxen. Provade det först men det funkade inte och då blev det DataSet. Men jag undrar om inte lösningen ovan löser det problemet också. Har inte haft tid att prova ännu.

Medlem sedan nov. 2003569 inlägg
#5

Får man fråga varför inte använda dataSet?. Det kan ju vara så att du vill spara ner värdena användaren skrivit i controllen i en databas eller xml-fil, detta ju gör dataset autmatiskt.

Medlem sedan apr. 2004778 inlägg
#6

Man får se till vad som behövs. Vi har ju varit inblandade i en DataSet diskussion tidigare och jag är fortfarande anti-DataSet. ;)
I vanliga fall bygger jag ASP.NET applikationer och då kör jag objekt och starkt typade collections. Där handlar det i och för sig inte om prestanda. Men den diskussionen behöver vi inte ta igen eftersom det finns en rätt lång tråd om det.

I det här fallet så är det min första WinForms applikation och jag har inte riktigt kommit så långt att jag fått ner alla specifikationer ännu. Men det är rätt mycket som skall utföras så jag kommer göra allt för att förbättra prestandan. Om DataSet passar bra så kommer jag använda det, annars hittar jag någon annan lösning.

I just den här applikationen så ska jag:
1. Hämta en xml-fil via URL. Filen innehåller en ruttlista med adresser
2. Matcha adresserna mot en annan xml-fil (eller databas) för att få ut koordinater
3. Skapa en textfil som innehåller den första ruttlistan men med koordinater istället för adresser
4. Aktivera ett 3:e parts program som använder textfilen i punkt 3 för att optimera ruttlistan
5. Ta den optimerade ruttlistan (kommaseparerad textfil) och matcha den med orginalruttlistan så att man får ruttlistan med adresser men nu i optimerad ordning.

Jag har alltså följande listor:
- Adresslista orginal där adresserna ser ut som (XML):
"Gatunamn 1", postnummer, "stad"
"c/o fnamn lnamn, Gatunamn 2, 2 tr", postnummer, "stad"
"Gatunamn 6", postnummer, "stad"
"Gatunamn 7, ö.g.", postnummer, "stad"

- Konverteringslista (kommaseparerad textfil, xml-fil eller databas)
10.9182,60, 60.0001,"Gatunamn 1","","postnummer"
10.9182,60, 60.0002,"Gatunamn 2","","postnummer"
10.9182,60, 60.0003,"Gatunamn 3","","postnummer"
10.9182,60, 60.0004,"Gatunamn 5-7","","postnummer"

- Resultatlistan (kommaseparerad textfil)
10.9182,60, 60.0001, "stad"
10.9182,60, 60.0002, "stad"
10.9182,60, 60.0004, "stad"
10.9182,60, 60.0004, "stad"

Har en tråd på gång på Pellesoft om detta, http://www.pellesoft.se/communicate/forum/view.aspx?msgid=146027&forumid=12&sum=1

Känner du att du vill bevisa kraften i DataSet och kan lösa problemet med matchningen smidigt så är du välkommen att skicka in en lösning. ;)

Medlem sedan nov. 2003569 inlägg
#7

Jag hade nog gjort såhär:

1. Läs in adresslistan i ett DataSet(adress-dataset). Om det är XML skapas tabellerna och kolumnerna automatiskt i dataset:et så att det blir en kopia av XML filens struktur.

2. Skapa en ny kolumn som heter "koordinat" på tabellen i adress-dataset:et.

3. Skapa ett nytt DataTable(koordinat-datatable) och Läs in koordinatlistan i det.

4. Gör en ForEach på adress-dataSet:et och i den Foreach:en letar du upp alla koordinater i koordinat-DataTable(med Select eller Find) och lägger i din adress-dataset:s nya kolumn "koordinat".

5. Nu har du alla adresser från den första listan plus koordinaterna för dem. Sen gör du en sortering på adress-dataSet:et "koordinat" kolumn med hjälp av DataView så att den lägsta koordinaten kommer först.

Var det nåt sånt du tänkte dig? :)

Medlem sedan apr. 2004778 inlägg
#8

Tänkte berätta lite hur lösningen blev till slut. Eftersom det blev lite bråttom så är det inte den ultimata lösningen, det får bli lite uppdateringar längre fram. Huvudsaken är att den funkar och det går snabbt att få fram alla resultat.

Den kommaseparerade koordinatlistan jag fått importerade jag till en Accessdatabas.

Applikationen läser ner ordrarna i XML-format, rensar adressen, som följer en standard, så att gatunamn och nummer finns kvar och stoppar in allt i en tabell i accessdatabasen.

Därefter matchas ordrarna mot koordinater genom att jämföra orderns formatterade adress och stad med den adress och stad som finns i koordinattabellen. Long och lat koordinaterna läggs in i ordertabellen. Denna matchning görs med en sql-sats. De adresser som inte finns i koordinattabellen får 0 som koordinater.

Orderkoordinater och orderid plockas ut från ordertabellen och en textfil skapas enligt det format logistikprogrammet kräver. De ordrar som inte har koordinater lämnas utanför.

Logistikprogrammet startas och den skapade textfilen skickas in tillsammans med några parametrar som bestämmer hur optimeringen görs. Logistikprogrammet optimerar rutten, skriver om textfilen i rätt ordning och skapar även en kartbild i .bmp format.
Kan tillägga att jag även lägger till en start- och slutstopp i textfilen beroende på vilket leveransområde man valt. Detta pga att det stopp som ligger som start och slut i textfilen även ligger där efter optimeringen.

Min applikation går igenom textfilen rad för rad och lägger in sorteringsordningen i en kolumn i ordertabellen.

Applikationen plockar ut alla ordrar och sorterar dessa efter sorteringsordningen. En textfil skapas där namn, adress och produkter finns med. Sist i filen läggs de adresser som inte kunnat matchas.

Applikationen skickar textfilen till skrivaren och sedan även kartfilen så att allt skrivs ut.

Listan och kartan lämnas till chaufförerna som kör ut varorna.

Allt funkar kanon förutom att logistikprogrammet har vissa brister i optimeringen. Så dom har fått bakläxa och får förbättra sin produkt. Det är inte så bra när stopp 1 ligger i Liljeholmen, stopp 2 på Söder vid Hornstull och stopp 3 och 4 i Liljeholmen och Gröndal. Inte precis optimerat då, men dom vet tydligen var felet ligger... säger dom.

Som sagt, detta är inte den mest optimala lösningen men det viktiga var att få igång den. Eftersom det går hyfsat snabbt att få fram resultatet så funkar det bra. Men det blir väl lite ändringar och optimeringar efterhand när tid finnes.

267 ms totalt · 3 externa anrop · v20260731065814-full.b746b907
130 ms — hämta forumlista (db)
128 ms — hämta statistik (db)
137 ms — hämta tråd, inlägg och bilagor (db)