18. oktober 2004 - 07:30Der er
15 kommentarer og 1 løsning
Opbygning af ukendt tabel med ASP.NET
Jeg skal opbygge en html-tabel i ASP.NET ud fra et par lister af objekter. Den ene liste repræsenterer kolonnerne, mens den anden liste repræsenterer rækkerne. Jeg ved ikke på forhånd hvor mange der er af hver.
Jeg tror ikke på den bedste ASP.NET-måde at løse det på, er ved at gennemløbe begge lister og lave Response.Write el. lign. og skrive escaped html-kode i min codebehind.
Jeg kan imidlertid ikke se at en Repeater el. lign. kan benyttes til dette, da det involverer hardkodet html-kode i aspx'en. Det virker samtidig meget tungt at lave et DataSet ud fra objekterne og putte det DataSet ind i et DataGrid.
Hvad er det for nogle lister du har ? Databundne kontroller kan binde til de fleste listetyper (arrays mv) - f.eks. slipper du fint afsted med sådan en her:
Det er ikke en forudsætning at du skriver din template i aspx-koden - du kan sagtens gøre det programmatisk... Du siger bare til hvis du vil have et eksempel.
Men... hvis du skriver tilbage hvad det er for nogle lister, af hvilke typer objekter du har, vil jeg meget gerne komme med et mere konkret bud.
Det næste er et eksempel på en template der ikke er skrevet i aspx :
// først et grid DataGrid grid = new DataGrid(); grid.AutoGenerateColumns = false;
// en standardkolonne BoundColumn bc = new BoundColumn(); bc.HeaderText = "Overskrift"; bc.DataField = "FldString"; grid.Columns.Add(bc);
// og så en templatecolumn TemplateColumn tpc = new TemplateColumn(); tpc.HeaderText = "TemplateOverskrift"; tpc.ItemTemplate = new EditableColumn("FldDateTime"); grid.Columns.Add(tpc);
// datasource angive til en passende kilde grid.DataSource = PageDataSet; // databind og smid det ind på formen grid.DataBind(); Form1.Controls.Add(grid);
// // Den databrundne Template-kolonne // public class EditableColumn : ITemplate { private string _dataField; protected TextBox tb;
public string DataField { get{return _dataField;} set{_dataField = value;} }
public EditableColumn(string dataField) { _dataField = dataField; }
public void InstantiateIn(Control container) { TextBox tb = new TextBox(); tb.DataBinding+=new EventHandler(tb_DataBinding); container.Controls.Add(tb); }
Jeg prøver med dit eksempel nr. 2, da jeg både skal definere kolonner (et ukendt antal) og rækker.
Objekterne er netop nogle "hjemmelavede" objekter. Jeg har et ukendt antal objekter som er kolonner, og hvert af disse objekter indeholder en ArrayList med andre objekter der skal være rækkerne under den kolonne.
Kan jeg ikke indsætte rækkerne explicit. Det med at definere en stor DataSource går ikke rigtig her, synes jeg, når værdierne er delt op i en masse små logisk placerede Collections. Altså noget i den retning:
foreach (MyColumnObject myColumn in columnCollection) { bc = new BoundColumn(); bc.HeaderText = myColumn.StartDateTime.ToString("dd/MM/yy HH:mm"); bc.DataField = "Amount"; grid.Columns.Add(bc);
foreach (MyRowObject rowObject in myColumn.RowList) { BoundRow br = new BoundRow(); br.Content = rowObject.Amount; bc.Rows.Add(br); } }
Jeg ved godt ovenstående ikke er korrekt kode, men det illustrerer hvordan jeg ville ønske jeg kunne gøre.
og det blev frokost, og jeg har ikke haft tid :o( det bliver nok først engang iaften er jeg bange for, men jeg har ikke glemt det.
På det kode du har sendt ser det sådan lige umiddelbart ud som om du ville være bedre tjent med bare at generere tabellen dynamisk (som med det første eksempel), men ... vi kan lige skrives ved om det senere.
Jeg tror måske jeg er lidt i tvivl om hvad du forklarer med koden... er det sådan, at du kan have en kolonne der f.eks. har 3 rækker nedefter, og en anden kolonne ved siden af - der kun har f.eks. 2 osv ?
Altså f.eks. sådan her : c1 c2 c3 r1 r1 r1 r2 r2 r3
Jeg forstår godt hvad du mener. Og nej, det er ikke det jeg mener.
Jeg har et ukendt antal kolonner og et ukendt antal rækker. Men antallet af rækker er det samme for alle kolonner. Det lader vist til man ikke rigtig kan med de redskaber der.
Jeg tror det bliver til at jeg laver en tabel i et DataSet.
Jeg tror også det under alle omstændigheder vil være det letteste... altså at skabe en tabel i koden... Om du så gør det direkte til dit UI ved dynamisk tabelgenerering (som det første eksempel jeg sendte), eller om du laver en DataTable og sidenhen bruger et grid betyder ikke så meget. Datataballen har lidt mere potentiale på sigt synes jeg (du behøver ikke som udgangspunkt at lave et dataset med mindre du ønsker at arbejde med flere datatabeller med relationer imellem og den slags).
Lige præcis hvordan du gør det nemmest er lidt afhængig af de objekter du arbejder med, men du kan lige få et forslag til en skabelon her : (sådan lidt psoudoagtigt, og lidt i forhold til det du selv har skrevet)
// en klasse til en datatabel // de kan ca. det samme som "normale" tabeller i databaser // jeg har bare ikke rigtig brugt noget af det her :o) public class SampleTable : DataTable { // konstruktør som du smider din collection efter public SampleTable(SomeColumnCollection columnCollection) : base("SomeTableName") { // for alle kolonnetyper i din collection foreach(SomeColumn column in columnCollection) { // du har så sikkert et navn eller noget DataColumn c = this.Columns.Add(column.Name, typeof(string)); } } }
Du kan så bruge tabellen i koden lidt i denne stil : SampleTable table = new SampleTable(someColumnCollection); foreach (SomeRowObject rowObject in SomeRowObjectCollection) { DataRow dr = table.NewRow(rowObject.Values); table.Rows.Add(dr); }
. . .
Ved ikke om det var lidt for lamt skrevet.... men du kan muligvis se en idé i det. Ellers må du lige sige til... Du kan eventuelt vise lidt mere af de objektertyper du har... Så kan det være jeg kan komme med et lidt mere brugbart bud.
Det var i hvert fald så lidt - glad for at du kunne bruge det :o) mvh (du får et svar her, men du spørger bare videre hvis du skulle får lyst :o)
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.