I'm currently working on an in house project, I've created a GridView connected to a SQL table which looks like this:
GridView1
I created the view content buttons using the following code:
<Columns>
<asp:ButtonField ButtonType="Button" Text="View Content" CommandName="Select" />
<asp:BoundField DataField="ContentID" HeaderText="ContentID" InsertVisible="False" ReadOnly="True" SortExpression="ContentID" />
<asp:BoundField DataField="Code" HeaderText="Code" SortExpression="Code" />
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
<asp:BoundField DataField="Description" HeaderText="Description" SortExpression="Description" />
<asp:BoundField DataField="URL" HeaderText="URL" Visible="true" SortExpression="URL" />
</Columns>
But this is where I am now stuck. I would like to click on the view content button and have it navigate to the URL on the selected row.
The URL comes from the SQL Table and there is a string so I'd imagine, it would need to be converted first but I could be wrong.
I started to put my code in the following:
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
GridViewCommandEventArgs x = (GridViewCommandEventArgs)e;
if (x.CommandName == "Select")
{
GridViewRow row = GridView1.SelectedRow;
}
}
Add your code in GridView1_RowCommand event of gridview:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Select")
{
GridViewRow row = (GridViewRow)(((BoundField)e.CommandSource).NamingContainer);
int index = row.RowIndex;
string url = (GridView1.Rows[index].FindControl("URL") as BoundField).Text;
Response.Redirect(url); // url can be from your sql table
}
}
Note: Don't forget to add OnRowCommand event in GrindView <asp:GridView ID="GridView1" runat="server" OnRowCommand="GridView1_RowCommand" >
GridViewRow row = (GridViewRow)(((BoundField)e.CommandSource).NamingContainer);
int index = row.RowIndex;
string url = (GridView1.Rows[index].FindControl("URL") as BoundField).Text;
Response.Redirect(url); // url can be from your sql table
So i made the change. Unfortunately, BoundField does not contain a definition for NamingContainer.
Also, GridView1.Rows[index].FindControl("URL") as BoundField fails due to the following error, cannot convert type 'system.web.ui.control' to 'system.web.ui.webcontrols.boundfield' via a reference conversion, boxing conversion, unboxing conversion or null type conversion.
Related
Hi i was just making a web application in asp.net to perform CRUD operations which include image file operations too. This web application consume a web service to perform the database operations.
When running on IIS i am stuck at following error.
" Unable to cast object of type 'System.String' to type 'System.Byte[]' "
Could you please help?. The same application code was working without any issues when the web service wasn't used.
Error:
enter image description here
Code for image view in FilmGrid.aspx.cs file
FilmService.FilmCrud objFCRUD = new FilmService.FilmCrud();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Refreshdata();
}
}
//To display entire film database as gridview
protected void Refreshdata()
{
DataSet dTbl = new DataSet();
XmlElement exelement = objFCRUD.SelectRecord(0);
if (exelement != null)
{
XmlNodeReader nodeReader = new XmlNodeReader(exelement);
dTbl.ReadXml(nodeReader, XmlReadMode.Auto);
gvMovies.DataSource = dTbl;
gvMovies.DataBind();
}
}
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRowView dr = (DataRowView)e.Row.DataItem;
string imageUrl = "data:image/jpg;base64," + Convert.ToBase64String((byte[])dr["poster"]);
(e.Row.FindControl("Image1") as Image).ImageUrl = imageUrl;
}
}
My FilmGrid.aspx file
<asp:GridView ID="gvMovies" HeaderStyle-BackColor="#3AC0F2" HeaderStyle-ForeColor="White" runat="server" BorderWidth="2px" CellPadding="4" OnRowDataBound="OnRowDataBound" AutoGenerateColumns="false" Height="217px" Width="1491px">
<Columns>
<asp:BoundField DataField="film_id" HeaderText ="Film Id" />
<asp:BoundField DataField="film_name" HeaderText ="Film Name" />
<asp:BoundField DataField="actor" HeaderText ="Actor" />
<asp:BoundField DataField="actress" HeaderText ="Actress" />
<asp:BoundField DataField="pub_date" HeaderText ="Published Date" />
<asp:BoundField DataField="director" HeaderText ="Director" />
<asp:BoundField DataField="producer" HeaderText ="Producer" />
<asp:BoundField DataField="prod_cost" HeaderText ="Production Cost" />
<asp:BoundField DataField="dist_cost" HeaderText ="Distribution Cost" />
<asp:BoundField DataField="category" HeaderText ="Category" />
<asp:BoundField DataField="cert_category" HeaderText ="Certified Category" />
<asp:TemplateField><ItemTemplate><asp:Image ID="Image1" HeaderText ="Poster" runat="server" Width="122px" Height="148px"/></ItemTemplate></asp:TemplateField>
<asp:TemplateField><ItemTemplate><asp:LinkButton ID="lnkedit" runat="server" Text="Edit" PostBackUrl='<%# "~/AddFilm.aspx?film_id="+Eval("film_id") %>'/></ItemTemplate></asp:TemplateField>
</Columns>
</asp:GridView>
Looks like dr["poster"] returns a string and you can't directly cast (which here means using (your_type_here)) convert a string to a byte[]. Look at Piotr Szuflicki's solution for how to properly convert a string to a byte[].
You cannot directly cast string to byte[].
You have to use, for example Encoding class.
byte[] array = Encoding.ASCII.GetBytes("Your string");
https://www.c-sharpcorner.com/article/c-sharp-string-to-byte-array/
Or you can try taking char array from the string and then cast each char to byte.
I am using GridView for Showing Some Data with Editable Format. But When I am Editing the GridView row I don't get the Value of editable Textbox. Again I get the old Value.Please any one give some Suggestion.
Thanks in Advance...
Aspx Code:
<asp:GridView ID="grdAppSetting" AutoGenerateEditButton="true" AutoGenerateDeleteButton="true" HeaderStyle-BackColor="#1abc9c" HeaderStyle-ForeColor="White" CssClass="t-transform m-t-30" HeaderStyle-BorderWidth="5px"
runat="server" OnRowCancelingEdit="grdAppSetting_RowCancelingEdit1" OnRowDeleting="grdAppSetting_RowDeleting" OnRowUpdating="grdAppSetting_RowUpdating"
OnRowEditing="grdAppSetting_RowEditing" AutoGenerateColumns="false" BorderColor="#1abc9c">
<Columns>
<asp:BoundField DataField="Key Name" HeaderText="Key Name" ReadOnly="true" ItemStyle-CssClass="p-l-10" ItemStyle-Width="100" />
<asp:BoundField DataField="Value" HeaderText="Value" ItemStyle-Height="40px" ItemStyle-Width="50%" ItemStyle-CssClass="p-l-10" ControlStyle-CssClass="form-control" />
</Columns>
</asp:GridView>
C# Code:
protected void grdAppSetting_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
string Value = ((grdAppSetting.Rows[e.RowIndex].Cells[2].Controls[0]) as TextBox).Text;
string KeyName = grdAppSetting.Rows[e.RowIndex].Cells[1].Text;
if (appSettingsSection != null)
{
appSettingsSection.Settings[KeyName].Value = Value;
configuration.Save();
}
grdAppSetting.EditIndex = -1;
BindAppSettingGrid();
}
Problem occurred in the following line,
string Value = ((grdAppSetting.Rows[e.RowIndex].Cells[2].Controls[0]) as TextBox).Text;
Is this is correct to get the editable textbox value???
I am trying to complete a simple task;
a gridview column gets an integer data if integer is equals to zero print "active" and set the commandname of the linkbutton to active else set linkbutton text and command value to inactive.
here is what I have so far
<Columns>
<asp:BoundField HeaderText = "User Name" DataField="UserName"
HeaderStyle-Width="16%" ItemStyle-HorizontalAlign="Center" />
<asp:BoundField HeaderText = "Role" DataField="RoleNAME"
HeaderStyle-Width="14%" ItemStyle-HorizontalAlign="Center" />
<asp:BoundField HeaderText = "Group" DataField="GroupName"
HeaderStyle-Width="12%" ItemStyle-HorizontalAlign="Center" />
<asp:ButtonField ButtonType="link" CommandName = "Active"
HeaderText="Status" Text="Active"
HeaderStyle-Width="10%" ItemStyle-HorizontalAlign="Center" />
<asp:ButtonField ButtonType="link" CommandName = "Edit"
HeaderText="" Text="Edit/View"
HeaderStyle-Width="10%" ItemStyle-HorizontalAlign="Center" />
</Columns>
codebehind
protected void grdMyQueue_RowdataBound(object sender, GridViewRowEventArgs e)
{
// In template column,
if (e.Row.RowType == DataControlRowType.DataRow)
{
var obj = (User)e.Row.DataItem;
if (obj.isDisabled == 0)
{
LinkButton linkButton = new LinkButton();
linkButton.Text = "Active";
linkButton.Enabled = true;
linkButton.CommandName = "Active";
//linkButton.CommandArgument = e.Row. //this might be causing the problem
e.Row.Cells[3].Controls.Clear();
e.Row.Cells[3].Controls.Add(linkButton);
}
else
{
LinkButton linkButton = new LinkButton();
linkButton.Text = "InActive";
linkButton.Enabled = true;
linkButton.CommandName = "InActive";
e.Row.Cells[3].Controls.Add(linkButton);
}
}
}
However when I Click the active linkbutton on the cell I get an error at onrowcommand function
protected void OnRowCommand(object sender, GridViewCommandEventArgs e)
{
int index = Convert.ToInt32(e.CommandArgument); // this is the error line
GridViewRow gvRow = userManager.Rows[index];
TableCell usrName = gvRow.Cells[0];
string userName = usrName.Text;
....
How can I manage to change LinkButton text and CommandName depending on that integer data?
P.S I tried Eval but I couldnt figure out whats going on....
I would simply return the data from your data source, as intended. Then I would use an Update Panel to avoid the Postback that will occur from your Link Button. As for the text modifying I would use Javascript, so Javascript will read the page on the client. So when your data source returns:
One
One
Two
One
The Javascript can analyze those rows, then modify the internal cell within the Grid quite painless.
An example of Javascript:
$(".Activator").each(function () {
if ($(this).prev().find(':checkbox').prop('checked')) {
$(this).text("Deactivate");
}
});
This example will validate if a checkbox is checked, if it is modify the internal text to the class .Activator.
Then the internal item in the Grid for code on front-end would look like:
<asp:TemplateField HeaderText="Active">
<ItemTemplate>
<asp:CheckBox
ID="CustomerCheck" runat="server"
Checked='<%# Eval("Active") %>'
Enabled="false" />
<asp:LinkButton
ID="lbCustomerActive" runat="server"
Text="Activate"
CommandName="OnActivate"
ToolTip='<%# "Activate or Deactivate Course: " + Eval("CourseID") %>'
OnClick="CustomerCheck_Click"
CssClass="Activator">
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
As you can see, as the internal data is changed the Javascript will automatically adjust the value for me every time the Data Source is binded again. Which the CustomerCheck_Click would execute the code on the server, which will read the Command Argument which contains the Row Id. Which will Update that particular record without a problem and rebind the Grid. (Partially lied, I'm parsing the Tooltip).
You would instantiate on server side like:
((LinkButton)sender).ToolTip;
hey I'm using to buttons in a gridview each which I want to assign to specific action involves retrieving certain cell values from the gridview columns
I tried using
GridViewRow row = (GridViewRow (((Button)e.CommandSource).NamingContainer);
but it gives me Unable to cast object of type 'System.Web.UI.WebControls.GridView' to type 'System.Web.UI.WebControls.Button'.
I also tried
int index = Convert.ToInt32(e.CommandArgument);
GridViewRow row = GridView1.Rows[index];
it gives me the following error
Specified argument was out of the range of valid values.
Parameter name: index
note that when I tried to specify the commandParameters property of the ButtonField the compiler said that it's not a valid parameter for the ButtomField
and I have 8 columns in the gridview so its not out of range
or alternatively could I use more than one select command button
if so how to say which one is clicked??
please help me im desperate
ASP code:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="AcitivityId" DataSourceID="SqlDataSource1" Height="304px" Width="912px" OnRowCommand="GridView1_RowCommand">
<Columns>
<asp:BoundField DataField="AcitivityId" HeaderText="AcitivityId" InsertVisible="False" ReadOnly="True" SortExpression="AcitivityId" />
<asp:BoundField DataField="ActiviityName" HeaderText="ActiviityName" SortExpression="ActiviityName" />
<asp:BoundField DataField="ActivityLocation" HeaderText="ActivityLocation" SortExpression="ActivityLocation" />
<asp:BoundField DataField="ActivityStartDate" HeaderText="ActivityStartDate" SortExpression="ActivityStartDate" />
<asp:BoundField DataField="ActivityDueDate" HeaderText="ActivityDueDate" SortExpression="ActivityDueDate" />
<asp:BoundField DataField="ActivityDescription" HeaderText="ActivityDescription" SortExpression="ActivityDescription" />
<asp:ButtonField ButtonType="Button" CommandName="Avaliable" Text="Show avaliable buses" />
<asp:ButtonField ButtonType="Button" CommandName="Assigned" Text="Show assigned buses "/>
</Columns>
</asp:GridView>
I use this code in a number of places on my site to get the row from an object triggering a GridViewRowCommand
protected void btnUpdate_Command(object sender, CommandEventArgs e)
{
GridViewRow g = (GridViewRow)((Button)sender).NamingContainer;
// other stuff
}
Hope this helps.
In reference to Link loaded into my gridview try to navigate to my local server. The columns I have in the datagrid are Customer #, Description, Link.
I've got a function set up that's called on rowDataBound, but how do I retrieve what link is in the row so that I can edit it, and then rebind it to the datagrid?
protected void grdLinks_RowDataBound( object sender, GridViewRowEventArgs e )
{
if ( e.Row.RowIndex == 2 )
{
}
}
And here is my gridview code
<asp:GridView ID="grdLinks" runat="server" AutoGenerateColumns="False" DataSourceID="ldsCustomerLinks"
OnRowDataBound="grdLinks_RowDataBound" EmptyDataText="No data was returned."
DataKeyNames="ID" OnRowDeleted="grdLinks_RowDeleted" Width="80%" BackColor="White"
HorizontalAlign="Center" BorderColor="#999999" BorderStyle="None" BorderWidth="1px"
CellPadding="3" GridLines="Vertical">
<RowStyle BackColor="#EEEEEE" ForeColor="Black" />
<Columns>
<asp:BoundField DataField="CustomerNumber" HeaderText="Customer Number" SortExpression="CustomerNumber" />
<asp:BoundField DataField="Description" HeaderText="Description" SortExpression="Description" />
<asp:HyperLinkField DataTextField="Link" HeaderText="Link" SortExpression="Link" DataNavigateUrlFields="Link" Target="_blank" />
</Columns>
</asp:GridView>
<asp:LinqDataSource ID="ldsCustomerLinks" runat="server" ContextTypeName="ComplianceDataContext"
TableName="CustomerLinks" EnableDelete="true">
</asp:LinqDataSource>
If I'm understanding you correctly, you want to get the value of a data item called Link. If so, then something like this should work:
EDIT: I think what you're saying is that you want to grab the value Link from the database, manipulate it and then set the Url of the HyperLink to the new, manipulated value, if so then it would look like this:
ASPX Page (Updated to reflect posted code)
<Columns>
<asp:BoundField DataField="CustomerNumber" HeaderText="Customer Number" SortExpression="CustomerNumber" />
<asp:BoundField DataField="Description" HeaderText="Description" SortExpression="Description" />
<asp:TemplateField HeaderText="Link">
<ItemTemplate>
<asp:HyperLink ID="hlParent" runat="server" Text='<% #(Eval("Link")) %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
I modified the ASP from your original question by adding an ID and removing the reference to the NavigateUrl attribute from the HyperLink control.
Code
protected void grdLinks_RowDataBound( object sender, GridViewRowEventArgs e )
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string link = DataBinder.Eval(e.Row.DataItem, "Link") as string;
if (link != null && link.Length > 0)
{
// "FindControl" borrowed directly from DOK
HyperLink hlParent = (HyperLink)e.Row.FindControl("hlParent");
if (hlParent != null)
{
// Do some manipulation of the link value
string newLink = "https://" + link
// Set the Url of the HyperLink
hlParent.NavigateUrl = newLink;
}
}
}
}
RowDataBound is called for every row in the GridView, including headers, footers, etc. Therefore, you should start by examining only the rows containing data.
Once you're on a row, there are several ways to examine the cells. One is just to use the cell index (2 here). That seems simple in your situation, but will lead to frustration if you ever rearrange the columns.
Here's an example of that from MSDN:
void CustomersGridView_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
// Display the company name in italics.
e.Row.Cells[1].Text = "<i>" + e.Row.Cells[1].Text + "</i>";
}
A better way is to use FindControl with the item's ID.
protected void gvBarcode_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
HyperLink hlParent = (HyperLink)e.Row.FindControl("hlParent");
}
}
You may also want to look into letting the gridview do it for you.
You can use the datanavigateurlformatstring property to insert querystring parameters if that's what you are trying to do.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.hyperlinkfield.datanavigateurlformatstring.aspx