18. september 2004 - 09:59Der er
10 kommentarer og 1 løsning
Datagrid - flere kolonner via arraylist
Hejsa
Er der en der kan hjælpe med følgende problem.
Jeg har en række data fra en database som jeg gerne vil manipulere inden jeg viser dem i et datagrid. Hertil har jeg læst, at måden at gøre dette på er at oprette en arraylist med objekter, som så dernæst indlæses i datagrid'det.
Jeg kan bare ikke få det til at fungere og får fejlen: Object does not match target type og den pejer på linien: dgProducts.DataBind
Er der en som kan løse problemet for mig, synes jeg har søgt hele nettet igennem efter et svar, men som der nok kan gættes, har jeg ikke fundet en løsning :)
Alternative løsninger er selvf. også velkomne
mvh Dennis
Koden der benyttes er følgende:
Dim values as ArrayList= new ArrayList()
Dim intProductCategoryId as Integer = request.querystring("recordid") Dim drRecords as System.Data.IDataReader = getProducts(intProductCategoryId)
while drRecords.Read() values.Add (values.Add(New product(drRecords("ProductId"),drRecords("Name"),drRecords("Price"),drRecords("Stock"),drRecords("StockLimited")))) end while
Public Class product Private m_ProductId As Integer Private m_Name As String Private m_Price As Integer Private m_Stock As Integer Private m_StockLimited As Boolean
Public Sub New(ByVal ProductId, ByRef Name, ByVal price, ByVal stock, ByVal stocklimited) m_productid = productId m_name = name m_price = price m_stock = stock m_stocklimited = stocklimited End Sub
Public Property name() As String Get Return "<a href=""product_information_unique.aspx?recordid=" & m_ProductId & """>" & m_Name & "</a>" End Get Set(ByVal Value As String) m_name = Value End Set End Property
Public Property price() As String Get Return m_Price & " kr." End Get Set(ByVal Value As String) m_price = Value End Set End Property
Public Property stock As String Get if m_StockLimited = True then Return m_Stock else Return " " End if End Get Set(ByVal Value As String) m_stock = Value End Set End Property
Denne her ser lidt gusten ud... Er det det du vil ? while drRecords.Read() values.Add(values.Add(New product(drRecords("ProductId"),drRecords("Name"),drRecords("Price"),drRecords("Stock"),drRecords("StockLimited")))) end while
values.Add(values.Add(... skulle det ikke bare have været : values.Add(New product(...
Bortset fra det, er der ret mange muligheder hvis du vil lave dynamiske grids - du kan lige se et par simple modeller her :
Først en metode der bygger et grid op, og indsætter det i en form:
protected void CreateAndInsertGrid() { // et ny grid, hvor det angives at det ikke skal autogenerere kolonnerne DataGrid grid = new DataGrid(); grid.AutoGenerateColumns = false;
// der tilføjes en bunden kolonne BoundColumn bc = new BoundColumn(); bc.HeaderText = "FldString"; // overskriften bc.DataField = "FldString"; // den kolonne i datakilden der bindes til grid.Columns.Add(bc);
// og så en templatecolumn - her kan du gå lidt mere til vaflerne TemplateColumn tpc = new TemplateColumn(); tpc.HeaderText = "Template"; // vi vil bruge en særlig template ved almindelige items tpc.ItemTemplate = new EditableColumn("FldDateTime"); grid.Columns.Add(tpc);
Form1.Controls.Add(grid);
grid.DataSource = PageDataSet; grid.DataBind(); }
Og så skal EditableColumn så defineres :
// en speciel kolonne - der altid viser værdien i en tekstboks for editering public class EditableColumn : ITemplate { private string _dataField;
public EditableColumn(string dataField) { this._dataField = dataField; }
// påkrævet under interfacet ITemplate public void InstantiateIn(Control container) { // du kan sætte hvad som helst ind her, men for nu - en textbox TextBox tb = new TextBox(); // den skal kunne indgå i databindingsscenarier tb.DataBinding+=new EventHandler(tb_DataBinding); container.Controls.Add(tb); }
// her står så hvad der skal ske når der databindes private void tb_DataBinding(object sender, EventArgs e) { // værdien vises bare, men du kan jo her lave hvad som helst, og // manipulere data på alle de måde du vil. TextBox tb = (TextBox) sender; DataGridItem container = (DataGridItem) tb.NamingContainer; tb.Text = ((DataRowView)container.DataItem)[_dataField].ToString(); } }
'Metoden Protected Sub CreateAndInsertGrid() Dim grid As DataGrid = New DataGrid () grid.AutoGenerateColumns = False Dim bc As BoundColumn = New BoundColumn () bc.HeaderText = "FldString" bc.DataField = "FldString" grid.Columns.Add(bc) Dim tpc As TemplateColumn = New TemplateColumn () tpc.HeaderText = "Template" tpc.ItemTemplate = New EditableColumn ("FldDateTime") grid.Columns.Add(tpc) Form1.Controls.Add(grid) grid.DataSource = PageDataSet grid.DataBind() End Sub
'og den specielle kolonne Public Class EditableColumn Implements ITemplate Private _dataField As String
Public Sub New(ByVal dataField As String) Me._dataField = dataField End Sub
Public Sub InstantiateIn(ByVal container As Control) Dim tb As TextBox = New TextBox () AddHandler tb.DataBinding, AddressOf tb_DataBinding container.Controls.Add(tb) End Sub
Private Sub tb_DataBinding(ByVal sender As Object, ByVal e As EventArgs) Dim tb As TextBox = CType(sender, TextBox) Dim container As DataGridItem = CType(tb.NamingContainer, DataGridItem) tb.Text = CType(container.DataItem, DataRowView)(_dataField).ToString() End Sub End Class
Og du skal selvfølgelig også have en løsning på den model du bruger nu :
' generering af liste og grid Dim alist As ArrayList = New ArrayList () ' nedenstående svarer til det du gør med din reader... jeg har bare et dataset i forvejen For Each dr As DataRow In PageDataSet.Tables(0).Rows alist.Add(New Product (CType(dr("FldId"), Integer), dr("FldString").ToString())) Next Dim newGrid As DataGrid = New DataGrid () newGrid.DataSource = alist newGrid.DataBind() Me.Form1.Controls.Add(newGrid)
'og produktklassen Public Class Product Private someInt As Integer Private someText As String
Public ReadOnly Property ProductId() As Integer Get Return someInt End Get End Property
Public ReadOnly Property ProductName() As String Get Return someText End Get End Property
Public Sub New(ByVal someInt As Integer, ByVal someText As String) Me.someInt = someInt Me.someText = someText End Sub End Class
Det kan hurtigt blive en smule omfattende... Hvad siger du til et lille eksempel hvor du kan indsætte kolonner i forhold til en konfiguration, som du så parser... Konfigurationen kunne f.eks. være på sådan en form her :
<datafield>:<header>:<type>:<bredde>
hvor type så kunne være Normal, Editable
Et eksempel på en konfiguration kunne så være :
FldString:Overskrift:Editable:50
Hvilket ville resultere i at du fik indsat en kollonne med en tekstbok der er 50 pixels bred, indeholdende FldString-værdien fra datagrundlaget, og medfører kolonneoverskriften "Overskrift".
Tror bare jeg skriver et nyt spm til den tid :) Hvis jeg bliver tilpas træt af et problem. Du skal have mange tak og du virker ret stærk i data grids, så du må meget gerne se på det næste spm, jeg har, som jeg lige skal til at oprette nu om indsættelse og aflæsning af data i et datagrid :)
ok - jeg tager en kigger. også god weekend til dig :o) mvh
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.