How to include a column that dynamically demonstrates image in a Gridview

Asked

Viewed 1,299 times

3

I am generating a report and exporting to Excel, but as most reports the number of columns is dynamic and I am mounting the gridview dynamically. I need to demonstrate a column that displays images in the table, so I am including this column after having the result of my query, so far so good, but when I give the databind() this column that is in the datasource of gridview is not including in the control structure of gridview, thus not rendering and not demonstrating in the spreadsheet. Knowing that I store the images in the database in an array of bytes. Follow the snippet of my code below. Please help me!

  Dim grid As New GridView

        If posicaoLogo = -1 Then

            'Remove coluna identificador
            dataTable.Columns.RemoveAt(0)

            grid.DataSource = New DataView(dataTable)
            grid.DataBind()
        Else
            Dim testeGrid As DataView = New DataView(dataTable)

            'Tratamento Para inclusão da coluna tipo byte() devido a logomarca
            Dim row As DataRow
            Dim column As DataColumn
            ReDim listaLogo(0)
            ReDim listaIdentificadorMarca(0)

            i = 0
            For Each row In testeGrid.Table.Rows
                ReDim Preserve listaLogo(i)
                ReDim Preserve listaIdentificadorMarca(i)
                For Each column In testeGrid.Table.Columns
                    If column.ToString = "Identificador" Then
                        listaIdentificadorMarca(i) = row(column).ToString
                    End If
                    If column.ToString = "Logo" Then
                        If row(column).ToString = "SIM" Then
                            listaLogo(i) = "1"
                        Else
                            listaLogo(i) = "0"
                        End If
                    End If
                Next column
                i = i + 1
            Next row

            Dim dtcloned As Data.DataTable = testeGrid.Table.Clone
            Dim logomarcaMarca As DataColumn = New DataColumn("Logomarca")

            logomarcaMarca.DataType = GetType(System.Byte())

            dtcloned.Columns.Add(logomarcaMarca)

            i = 0
            Dim dtMarca As Data.DataTable = testeGrid.Table.Copy
            Dim logomarcaMarcaAux As DataColumn = New DataColumn("Logomarca")

            logomarcaMarcaAux.DataType = GetType(System.Byte())

            dtMarca.Columns.Add(logomarcaMarcaAux)
            For Each rowData As DataRow In dtMarca.Rows
                If listaLogo(i) = "1" Then
                    marca.identificador = listaIdentificadorMarca(i)
                    marca = marca.getImagem
                    rowData.SetField(dtMarca.Columns(dtMarca.Columns.Count - 1), marca.imagem)


                    dtcloned.ImportRow(rowData)
                Else
                    dtcloned.ImportRow(rowData)
                End If
                i = i + 1
            Next

            'Remove coluna de controle
            dtcloned.Columns.RemoveAt(dtMarca.Columns.Count - 2)

            'Remove coluna identificador
            dtcloned.Columns.RemoveAt(0)

            Dim dataviewMarcaAux As New DataView(dtcloned)
            grid.DataSource = dataviewMarcaAux


            grid.DataBind()
        End If
  • It makes me wonder, is it even possible to display an image just by passing the byte array directly to logoMarch and adding the column? Does this model really work? Check out this Stack post about this: http://stackoverflow.com/questions/17351045/showing-image-in-gridview-from-byte-array

  • So far I have not succeeded in passing an array of bytes or even the image itself, converting the array to System.Drawing.Image. I’m trying to search the forums somehow, but I found nothing that came in handy.

  • I will try to reproduce your example and comment here

  • Thank you! Waiting for your comment.

1 answer

1

Excuse the delay @user2992172, follow the best solution found following your example:

protected void Page_Load(object sender, EventArgs e)
    {
        DataTable dt = new DataTable();
        //Cria primeiras colunas
        dt.Columns.AddRange(new DataColumn[4] { new DataColumn("Id", typeof(int)),
                            new DataColumn("Name", typeof(string)),
                            new DataColumn("Country",typeof(string)), new DataColumn("logo",typeof(string)) });

        //Adiciona coluna com o logo       
        DataRow dr = dt.NewRow();
        dr["Id"] = "5";
        dr["Name"] = "Felipe";
        dr["Country"] = "Brazil";
        dt.Rows.Add(dr);

        GridView1.DataSource = dt;
        GridView1.DataBind();
    }

    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            Image ibtn = new Image();
            ibtn.ID = "imgPicture";
            e.Row.Cells[3].Controls.Add(ibtn);

            Image imgPicture = (Image)e.Row.FindControl("imgPicture");
            if ((imgPicture != null))
            {
                //Transforma o array de byte em base64 e atribui o controle Image à coluna
                System.Drawing.Image img = System.Drawing.Image.FromFile(@"C:\html5.png");
                byte[] imgArray = imageToByteArray(img);
                string base64String = Convert.ToBase64String(imgArray, 0, imgArray.Length);
                imgPicture.ID = "imgPicture";
                imgPicture.ImageUrl = "data:image/png;base64," + base64String;
            }
        }
    }

    public byte[] imageToByteArray(System.Drawing.Image imageIn)
    {
        MemoryStream ms = new MemoryStream();
        imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
        return ms.ToArray();
    }

I had to do it in C# but I believe the idea is the same and migrating the code is smooth. Just as you could not directly assign the control in Datatable and pass to Gridview, so I used Rowdatabound to create the control in Cell, transform the byte array into Base64 and play to the Imageurl attribute of the Image control. The result:

inserir a descrição da imagem aqui

Note that in your case you do not need to load an image of a file as I did in Fromfile(""), as you already have an array of bytes you already go straight to the Tobase64string() method. In ASPX there is only the grid declaration:

 <asp:GridView ID="GridView1" runat="server" OnRowDataBound="GridView1_RowDataBound"></asp:GridView>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.