I am using Visual Studio 2017 with vb.net. I have a gridview in which one column is an image. I would like to click on the image and have the image pop-up in another box displaying the picture larger with a close button. I haven't programmed in forever, I'm relearning vb.net, and, of course, my boss needed this yesterday. So, just showing the image part of the grid, my code is:
<asp:TemplateField HeaderText="Image" ItemStyle-HorizontalAlign="Center" ItemStyle-Width="50px">
<ItemTemplate>
<asp:Imagebutton ID="Img" runat="server" ImageUrl='<%# Eval("ImageBase64", "{0}") %>' ControlStyle-Width="100" ControlStyle-Height = "100" />
</ItemTemplate>
</asp:TemplateField>
So, the image shows in the grid:
Imports System.Configuration
Imports System.Data.SqlClient
Imports System.Drawing
Imports System.IO
Public Class _default
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim connectionStr As String = ConfigurationManager.ConnectionStrings("ictsqlConnection").ConnectionString
Using con As SqlConnection = New SqlConnection(connectionStr)
'open
con.Open()
Using cmd As SqlCommand = New SqlCommand("SELECT SurplusId, Department, Category, Item, VehicleMileage, SerialNo, AgeValueinYrs, AgeValueinMons, Visible, Image FROM Surplus", con)
Using da As SqlDataAdapter = New SqlDataAdapter(cmd)
Dim dt As DataTable = New DataTable()
'fill DataTable with data from database
da.Fill(dt)
'add column that will store the image as a base64 string
dt.Columns.Add("ImageBase64", GetType(System.String))
For i As Integer = 0 To dt.Rows.Count - 1
'convert image Byte() from database to base64 string and store in a new column in the DataTable
dt(i)("ImageBase64") = "data:image/jpg;base64," & Convert.ToBase64String(CType(dt(i)("Image"), Byte()))
Next
'remove column that contains Byte() from DataTable
dt.Columns.Remove("Image")
GridView1.DataSource = dt
GridView1.DataBind()
End Using
End Using
End Using
End Sub
End Class
I've searched for how to display picture in pop-up and nothing is working. The ImageButton does allow me to click on the picture (lol), but I can't figure out what code to put behind it so the image comes up in a pop-up. I appreciate any help you can give me. Thank you in advance.
CodePudding user response:
I suggest that you use jQuery.UI. (you probably have jQuery available anyway).
So, we attach a client side click event to the Grid.
Our markup is this:
<div style="width:50%">
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" CssClass="table" >
<Columns>
<asp:BoundField DataField="Fighter" HeaderText="Fighter" />
<asp:BoundField DataField="Engine" HeaderText="Engine" />
<asp:BoundField DataField="Thrust" HeaderText="Thrust" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField HeaderText="View">
<ItemTemplate>
<asp:ImageButton ID="btnImage" runat="server" Height="68px" Width="149px"
OnClientClick ="popimage(this);return false"
/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And our code to load the grid - pull image from database (used row data bound) is this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadGrid
End If
End Sub
Sub LoadGrid()
Using conn As New SqlConnection(My.Settings.TEST4)
Using cmdSQL As New SqlCommand("SELECT * FROM Fighters", conn)
conn.Open()
Dim rstData = New DataTable
rstData.Load(cmdSQL.ExecuteReader)
GridView1.DataSource = rstData
GridView1.DataBind()
End Using
End Using
End Sub
Protected Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
Dim btnImage As ImageButton = e.Row.FindControl("btnImage")
Dim gData As DataRowView = e.Row.DataItem
Dim IBytes() As Byte = gData.Item("Image")
btnImage.ImageUrl = "Data:Image/jpg;base64," Convert.ToBase64String(IBytes)
End If
End Sub
And now we have this:
So, we need to add a div for the pop dialog - so we add that, and the js code for the popup.
(this markup is right after the grid)
<div id="imagepop" style="display:none;text-align:center;height:80%">
<asp:Image ID="Image1" runat="server" ClientIDMode="Static"
style="height:96%"/>
</div>
<script>
function popimage(btn) {
FromImage = $(btn)
ToImage = $("#Image1")
ToImage.attr("src", FromImage.attr("src"))
pHeight = ($(window).height() * 0.96)
pWidth = ($(window).width() * 0.80)
myDialog = $("#imagepop");
myDialog.dialog({
title: "Fighter",
modal: true,
height: pHeight,
width: pWidth,
buttons: {
Ok: function () {
myDialog.dialog("close")
}
}
})
}
</script>
And now, if we click on the image button in the grid, we get this:
so, what the code does is "this" in the click event passes the image control we click on. We then grab the picture, and shove it into a "div", and then pop a jQuery.UI dialog - and you get the above.
Edit: Handle null image
Question was how to handle database rows with null columns? (well, we could feed the grid with a query that checks and does not include rows with no picture). But that might not be a valid assumption. Hence this would check for rows with no image:
Protected Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
Dim btnImage As ImageButton = e.Row.FindControl("btnImage")
Dim gData As DataRowView = e.Row.DataItem
If IsDBNull(gData.Item("Image")) = False Then
Dim IBytes() As Byte = gData.Item("Image")
btnImage.ImageUrl = "Data:Image/jpg;base64," Convert.ToBase64String(IBytes)
End If
End If
End Sub
Edit #2 - using jQuery and jQuery.UI
So, as a general rule, you download the jQuery, and jQuery.ui librarys. Drop them in a foler for your project - I tend to create a folder called scripts, and place jQuery, and jQuery.UI into that folder. Hence, you reference(s) in that page will look "something" like this:
<link href="../Content/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="../Scripts/jquery-1.12.4.js"></script>
<script src="../Scripts/jquery-ui-1.12.1.js"></script>
<script src="../Scripts/bootstrap.js"></script>
But, in place of downloading - you can use CDN (content delivery network). That's just a fancy term that in place of downloading and dropping those JavaScript librares into a folder, you reference their web site. Some people like this choice, some don't (since your web page is now referencing a outside external URL to consume those libaries). So, lets use this option for this example. Here is my full working mark-up for this page:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/smoothness/jquery-ui.css" />
</head>
<body>
<form id="form1" runat="server">
<div style="width:50%">
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" CssClass="table" >
<Columns>
<asp:BoundField DataField="Fighter" HeaderText="Fighter" />
<asp:BoundField DataField="Engine" HeaderText="Engine" />
<asp:BoundField DataField="Thrust" HeaderText="Thrust" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField HeaderText="View">
<ItemTemplate>
<asp:ImageButton ID="btnImage" runat="server" Height="68px" Width="149px"
OnClientClick ="popimage(this);return false"
/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
<div id="imagepop" style="display:none;text-align:center;height:80%">
<asp:Image ID="Image1" runat="server" ClientIDMode="Static"
style="height:96%"/>
</div>
<script>
function popimage(btn) {
FromImage = $(btn)
ToImage = $("#Image1")
ToImage.attr("src", FromImage.attr("src"))
pHeight = ($(window).height() * 0.96)
pWidth = ($(window).width() * 0.80)
myDialog = $("#imagepop");
myDialog.dialog({
title: "Fighter",
modal: true,
height: pHeight,
width: pWidth,
closeText :"",
show : "fade",
buttons: {
Ok: function () {
myDialog.dialog("close")
}
}
})
}
</script>
</form>
</body>
</html>