asp:GridView HYPERLINKFIELD - asp code inside datanavigateurlformatstring - c#

I have a page to search products by their name.
In many pages I work with product codes. If the user does not know the product code, I let him go to this page, search by name, and then select one of the results and get back to the page he came from.
In the results of the search by name I set an HyperLinkField that will redirect to a certain page , with a paramter of the product code.
My code is like this:
<asp:GridView ID="GridView1" Runat="server"
DataSource='<%# GetData(pName.Text) %>' AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="Name">
<ItemStyle HorizontalAlign="Center"
VerticalAlign="Middle"></ItemStyle>
</asp:BoundField>
<asp:BoundField DataField="Code"></asp:BoundField>
<asp:ImageField ControlStyle-Width="150px" ControlStyle-Height="150px" DataImageUrlField="PictureURL" ></asp:ImageField>
<ASP:HYPERLINKFIELD text=">>" datanavigateurlfields="Code" datanavigateurlformatstring="priceUpdater.aspx?ProductCode={0}"></ASP:HYPERLINKFIELD>
</Columns>
</asp:GridView>
Where GetData is a function that returns an object of type Product with the fields, name,Code,image etc.
As you can see, this link in the HYPERLINKFIELD will redirect to a page called priceUpdater with the parameter of the product code.
I want this page to be dynamic.
I have tried to add a paramter to the search page like this
<%string pageRequested = Page.Request.QueryString["SearchScreen"];%>
and now im trying to use the HYPERLINK like this:
<ASP:HYPERLINKFIELD text=">>" datanavigateurlfields="Code" datanavigateurlformatstring="<%=pageRequested%>.aspx?ProductCode={0}"></ASP:HYPERLINKFIELD>
But the page that the link reffers to is just as plain text as wrriten (http://mysite.com/%3C%=pageRequested%>.aspx?ProductCode=2450)
How can I make this work?
Thank you!

If you want to use HyperLinkField you need to extend datasource object returned by GetData method with value that comes with pageRequested query string parameter.
In that case markup for HyperLinkField will be following:
<asp:HyperLinkField text=">>"
datanavigateurlfields="PageRequested,Code"
datanavigateurlformatstring="{0}.aspx?ProductCode={1}"></asp:HyperLinkField>
But this will work only if you add PageRequested as a public field or property to an object that is returned by GetData method.
If this is not an option than you need to implement your own "LinkField" control inherited from DataControlField or use ItemTemplate as it was suggested by Nitin.

Try with that:
<asp:TemplateField>
<ItemTemplate>
<ASP:HYPERLINK text=">>" NavigateUrl='<%# String.Format("~/{0}.aspx?ProductCode={1}",Page.Request.QueryString["SearchScreen"],Eval("Code")) %>'></ASP:HYPERLINK>
</ItemTemplate>
</asp:TemplateField>

Replace HYPERLINKFIELD with TemplateField containing HyperLink and bind it in grid's rowdatabound event
ASPX:
<asp:GridView ID="GridView1" runat="server" DataSource='<%# GetData(pName.Text) %>'
OnRowDataBound="Grd_RowDatabound"
AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="Name">
<ItemStyle HorizontalAlign="Center" VerticalAlign="Middle"></ItemStyle>
</asp:BoundField>
<asp:BoundField DataField="Code"></asp:BoundField>
<asp:ImageField ControlStyle-Width="150px" ControlStyle-Height="150px" DataImageUrlField="PictureURL">
</asp:ImageField>
<asp:TemplateField>
<ItemTemplate>
<asp:HyperLink ID="lnkNavigate" runat="server" NavigateUrl="" Text=">>"></asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
CODEBEHIND
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
GridView1.DataBind();
}
public List<myData> GetData(string param)
{
List<myData> lst = new List<myData>();
lst.Add(new myData() { Name = "Hello", Code = "World", PictureURL = "Images/Select.png" });
return lst;
}
public string pageRequested
{
get {
return Page.Request.QueryString["SearchScreen"];
}
}
protected void Grd_RowDatabound(Object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
HyperLink lnkNavigate = (HyperLink)e.Row.FindControl("lnkNavigate");
if (lnkNavigate != null)
{
myData obj = (myData)e.Row.DataItem;
lnkNavigate.NavigateUrl = pageRequested + ".aspx?ProductCode="+obj.Code;
}
}
}
}
public class myData
{
public string Name { get; set; }
public string Code { get; set; }
public string PictureURL { get; set; }
}

Related

asp:GridView -> asp:TemplateField Calling Public Method Not Available Inside Control

I've been migrating aspx pages to a new ASP.NET WebApplication. I use the calling of public method inside Gridview quite a bit. But my inpage reference can't see the code behind method.
I'm using framework 4.7.2. I get the
ERROR: CS0103 The name 'GetReturnedString' does not exist in the
current context
All my other server controls are accessible, jut not these public defined methods. No luck in Google :(
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataSourceID="SqlDataSource1">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Literal ID="ltlString" runat="server"
Text='<%# GetReturnedString(Eval("FieldExample1").ToString())%>'>
</asp:Literal>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
My example code behind looks like this:
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
public string GetReturnedString(string fieldval1)
{
var outValue = "Something";
return outValue;
}
}
I would DataBind the GridView from the code behind page and add the something to the datatable column before databind.
Then the aspx page would have:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" >
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Literal ID="ltlString" runat="server"
Text='<%# (Eval("FieldExample1").ToString()) %>'>
</asp:Literal>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
The code behind file:
DataTable dtB = new DataTable();
dtB = //get the datatable from your data source
if (dtB != null && dtB.Rows.Count > 0)
{
foreach (DataRow drB in dtB.Rows)
{
drB["FieldExample1"] = GetReturnedString() + drB["FieldExample1"];
}
}
GridView1.DataSource = dtB;
GridView1.DataBind();
public string GetReturnedString()
{
var outValue = "Something ";
return outValue;
}
Have a look. You can do the formatting, etc.
At least it works on my test page and should work for you too, I hope.

Pass client id to code behind

Is there some way to pass the unique client id to codebehind? I have a imagebutton in a gridview and I wish to do something like this:
<asp:ImageButton ID="imbView" runat="server" ToolTip="View details" ImageUrl="~/css/images/View.png" CommandName="wView" CommandArgument='#<%=imbView.ClientID%>' />
On debugging though I see that my CommandArgument is #<%=imbView.ClientID%>..
To specify: I want to pass something that uniquely identifies generated elements (and I thought that the ClientID would be a good way to identify it).
Huh ?
Assuming you have
<asp:ImageButton ID="imbView" runat="server" ToolTip="View details" ImageUrl="~/css/images/View.png" CommandName="wView" OnCommand="aaa" />
then -
protected void aaa(object sender, CommandEventArgs e)
{
var a= (sender as Control).ClientID;
}
Here is how you retrieve CommandArgument inside RowCommand event.
You can also use e.CommandSource as ImageButton inside RowCommand event.
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="False"
OnRowCommand="GridView1_RowCommand">
<Columns>
<asp:TemplateField HeaderText="Detail">
<ItemTemplate>
<asp:ImageButton ID="imbView" runat="server"
ToolTip="View details" ImageUrl="~/css/images/View.png"
CommandName="wView"
CommandArgument='<%# Eval("Id") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="Name" DataField="Name">
</asp:BoundField>
</Columns>
</asp:GridView>
Code Behind
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GridView1.DataSource = new List<Item>
{
new Item {Id = 1, Name = "John"},
new Item {Id = 2, Name = "Eric"},
};
GridView1.DataBind();
}
}
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "wView")
{
var imageButton = e.CommandSource as ImageButton;
string clientId = imageButton.ClientID;
int id = Convert.ToInt32(e.CommandArgument);
}
}

A field or property with the name 'OrderID' was not found on the selected data source

Working on Multilevel grid view in asp.net, getting this error continuously. Binding the list is causing this error. The GridViewOrder is not getting the OrderID property but i have defined it.
The code for classes are:
public class Customer
{
public List<Order> Orders { get; set; }
}
The function calling inner grid is:
protected void GridViewCustomer_RowDataBound(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
string customerID = GridViewCustomer.DataKeys[e.Row.RowIndex].Value.ToString();
GridView GridViewOrders = (GridView)e.Row.FindControl("GridViewOrders");
var lstOrders = from orders in SortCustomer()
where orders.CustomerID == customerID
select orders.Orders;
GridViewOrders.DataSource = lstOrders.ToList();
GridViewOrders.DataBind(); // This line generating error
}
}
The aspx code is as:
<asp:TemplateField HeaderText="Orders">
<ItemTemplate>
<asp:GridView ID="GridViewOrders" runat="server"
AutoGenerateColumns="False" >
<Columns>
<asp:BoundField DataField="OrderID" HeaderText="Order Id" />
<asp:BoundField DataField="OrderDate" HeaderText="Order Date" />
<asp:BoundField DataField="Total" HeaderText="Total" DataFormatString="{0:c}" />
</Columns>
</asp:GridView>
</ItemTemplate>
</asp:TemplateField>
You need SelectMany here, cause currently you are trying to bind GridView to a list of lists of orders:
var lstOrders = SortCustomer().Where(c => c.CustomerID == customerID)
.SelectMany(c => c.Orders);

Data Lost from UserControl when I use RadGrid EditForm with UserControl

I use RadGrid EditForm with UserControl like this sample Telerik Sample
<telerik:RadGrid ID="personGrid" runat="server" AutoGenerateColumns="False" OnEditCommand="personGrid_EditCommand" OnUpdateCommand="personGrid_UpdateCommand">
<MasterTableView DataKeyNames="ID" CommandItemDisplay="Top">
<EditFormSettings UserControlName="PersonItemsUC.ascx" EditFormType="WebUserControl">
</EditFormSettings>
<Columns>
<telerik:GridBoundColumn UniqueName="ID" Display="false" HeaderText="ID" DataField="ID">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn UniqueName="Name" HeaderText="Name" DataField="Name">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn UniqueName="Family" HeaderText="Family" DataField="Family">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn UniqueName="Age" HeaderText="Age" DataField="Age">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn UniqueName="MobileNo" HeaderText="MobileNo" DataField="MobileNo">
</telerik:GridBoundColumn>
<telerik:GridEditCommandColumn EditText="Update" UniqueName="EditCommandColumn">
</telerik:GridEditCommandColumn>
<telerik:GridButtonColumn UniqueName="DeleteColumn" Text="Delete" CommandName="Delete">
</telerik:GridButtonColumn>
</Columns>
</MasterTableView>
</telerik:RadGrid>
and I have UserControl like this (have Person Info data)
I have method in My Usercontrol (GetDataFromControls)
public Person GetDataFromControls()
{
var sKey = typeof(Person).FullName + "Keys";
var p = new Person();
p.ID = Convert.ToInt32(SessionManager.Instance[sKey]); // ID store in Session with personGrid_EditCommand method
p.Name = txtName.Text;
p.Family = txtFamily.Text;
p.Age = Convert.ToInt32(txtAge.Text);
p.MobileNo = txtMobileNo.Text;
return p;
}
can get data from textboxes and other controls and set to Person instanse
OK now I want to update data so use this method in my page.aspx
protected void personGrid_UpdateCommand(object sender, GridCommandEventArgs e)
{
var userControl = e.Item.FindControl(GridEditFormItem.EditFormUserControlID) as PersonItemsUC;
if (userControl != null)
{
var p = userControl.GetDataFromControls(); //HERE
_personBusiness.Update(p);
}
}
first I found my usercontrol in UpdateCommand method and then call GetDataFromControls method but except ID that get from Session other data lost !!! all textboxes is empty
How can i call GetDataFromControls() method with valid data ?
Another solution that came to my mind saving GetDataFromControls to Session by this property
public Person CurrentEntity
{
get
{
var key = typeof(Person).FullName;
return SessionManager.Instance[key] as Person;
}
set
{
var key = typeof(Person).FullName;
SessionManager.Instance.Add(key, value);
}
}
and then call CurrentEntity instead of GetDataFromControls()
protected void personGrid_UpdateCommand(object sender, GridCommandEventArgs e)
{
var userControl = e.Item.FindControl(GridEditFormItem.EditFormUserControlID) as PersonItemsUC;
if (userControl != null)
{
var p = userControl.CurrentEntity; //HERE
_personBusiness.Update(p);
}
}
but I dont know when fill CurrentEntity in which event into my UserControl ?
CurrentEntity = GetDataFromControls(); // When assign method to CurrentEntity in My UserControl ???
Can anyone suggest good solution for calling GetDataFromControls from UserControl in Page.aspx without lost data ???
Please try with the below code snippet.
ASPX
<body>
<form id="form1" runat="server">
<div>
<telerik:RadScriptManager ID="RadScriptManager1" EnablePageMethods="true" runat="server">
</telerik:RadScriptManager>
<telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">
</telerik:RadAjaxManager>
<telerik:RadGrid ID="RadGrid1" runat="server" AutoGenerateColumns="false" OnNeedDataSource="RadGrid1_NeedDataSource"
AllowMultiRowEdit="true" OnUpdateCommand="RadGrid1_UpdateCommand">
<PagerStyle AlwaysVisible="true" />
<MasterTableView DataKeyNames="ID" CommandItemDisplay="Top">
<Columns>
<telerik:GridBoundColumn DataField="ID" UniqueName="ID" HeaderText="ID">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn DataField="Name" UniqueName="Name" HeaderText="Name">
</telerik:GridBoundColumn>
<telerik:GridEditCommandColumn></telerik:GridEditCommandColumn>
</Columns>
<EditFormSettings UserControlName="WebUserControl1.ascx" EditFormType="WebUserControl">
<EditColumn UniqueName="EditCommandColumn1">
</EditColumn>
</EditFormSettings>
</MasterTableView>
</telerik:RadGrid>
</div>
</form>
</body>
ASPX.CS
public partial class Forum : System.Web.UI.Page
{
protected void RadGrid1_NeedDataSource(object sender, GridNeedDataSourceEventArgs e)
{
List<Employee> list = new List<Employee>();
list.Add(new Employee() { ID = 1, Name = "Name1" });
list.Add(new Employee() { ID = 2, Name = "Name2" });
list.Add(new Employee() { ID = 3, Name = "Name3" });
list.Add(new Employee() { ID = 4, Name = "Name4" });
list.Add(new Employee() { ID = 5, Name = "Name5" });
RadGrid1.DataSource = list;
}
protected void RadGrid1_UpdateCommand(object sender, GridCommandEventArgs e)
{
GridEditableItem editedItem = e.Item as GridEditableItem;
UserControl userControl = (UserControl)e.Item.FindControl(GridEditFormItem.EditFormUserControlID);
string strName = (userControl.FindControl("TextBox1") as TextBox).Text; //Get usercontrol data
string strName1 = (userControl as WebUserControl1).GetDataFromControls(); //Call the usercontrol Method
//Perform your operation here
}
}
ASCX
<%# Control Language="C#" AutoEventWireup="true" CodeFile="WebUserControl1.ascx.cs" Inherits="WebUserControl1" %>
<%# Register TagPrefix="telerik" Namespace="Telerik.Web.UI" Assembly="Telerik.Web.UI" %>
your Usercontrol......
<br />
<asp:Label ID="Label1" runat="server"></asp:Label>
<br />
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Eval("Name") %>'></asp:TextBox>
<br />
<asp:Button ID="btnUpdate" Text="Update" runat="server" CommandName="Update"></asp:Button>
ASCX.CS
public partial class WebUserControl1 : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
public string GetDataFromControls()
{
return TextBox1.Text;
}
}
Let me know if any concern.

Add email url to gridview row, and open email window on double click

I have a GridView that has a column that contains emails. I want the user to be able to double click the row and an email link is activated to open an outlook window for an email. I've got the double click part down, but I'm no sure how to get the email from the row to create the url. I'll paste the code I do have below.
<asp:GridView ID="gvAllDOL" runat="server" Visible="False" PageSize="25" AutoGenerateColumns="False" OnDataBound="gvAllDOL_DataBound" DataSourceID="odsDOAll" OnRowDataBound="gvAllDOL_RowDataBound" DataKeyNames="sintDistrictOfficeID" OnRowCommand="gvAllDOL_RowCommand" OnSelectedIndexChanged="gvAllDOL_SelectedIndexChanged">
<Columns>
<asp:ButtonField Text="DoubleClick" CommandName="DoubleClick" Visible="false" />
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblid" runat="server" Text='<%# Bind("sintDistrictOfficeID") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="sintDistrictOfficeID" HeaderText="id" SortExpression="sintDistrictOfficeID" />
<asp:BoundField DataField="vcharDOLOfficeName" HeaderText="DOL Office Name" SortExpression="vcharDOLOfficeName" />
<asp:BoundField DataField="vcharDOLCity" HeaderText="City" SortExpression="vcharDOLCity" />
<asp:BoundField DataField="vcharDOLState" HeaderText="State" SortExpression="vcharDOLState" />
<asp:BoundField DataField="intBatchCount" HeaderText="Number Batches" SortExpression="intBatchCount" />
<asp:BoundField DataField="intCaseCount" HeaderText="Number Cases" SortExpression="intCaseCount" />
<asp:BoundField DataField="intExamCount" HeaderText="Number Examiners" SortExpression="intExamCount" />
</Columns>
</asp:GridView>
protected void gvCE_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes.Add("onMouseOver", "Highlight(this)");
e.Row.Attributes.Add("onMouseOut", "UnHighlight(this)");
// Get the LinkButton control in the second cell
LinkButton _doubleClickButton = (LinkButton)e.Row.Cells[0].Controls[0];
// Get the javascript which is assigned to this LinkButton
string _jsDouble =
ClientScript.GetPostBackClientHyperlink(_doubleClickButton, "");
// Add this JavaScript to the ondblclick Attribute of the row
e.Row.Attributes["ondblclick"] = _jsDouble;
}
}
protected void gvCE_RowCommand(object sender, GridViewCommandEventArgs e)
{
string email = ((Label)gvCE.Rows[0].Cells[1].FindControl("lblEmail")).Text; (this doesn't work)
GridView _gridView = (GridView)sender;
string _commandName = e.CommandName;
switch (_commandName)
{
case ("DoubleClick"):
Response.Redirect("<a href=mailto:" + email + ">");
break;
}
}
protected override void Render(HtmlTextWriter writer)
{
foreach (GridViewRow r in gvAllDOL.Rows)
{
if (r.RowType == DataControlRowType.DataRow)
{
Page.ClientScript.RegisterForEventValidation
(r.UniqueID + "$ctl00");
Page.ClientScript.RegisterForEventValidation
(r.UniqueID + "$ctl01");
}
}
foreach (GridViewRow r in gvCE.Rows)
{
if (r.RowType == DataControlRowType.DataRow)
{
Page.ClientScript.RegisterForEventValidation
(r.UniqueID + "$ctl00");
Page.ClientScript.RegisterForEventValidation
(r.UniqueID + "$ctl01");
}
}
base.Render(writer);
}
Convert your email field into template one. Add the following code and then try playing with it:
<asp:HyperLink ID="EmailLink" runat="server" Text='Email' NavigateUrl=
"mailto:" + '<%# Eval("yourBoundEmailFieldNameHere") %>'
</asp:HyperLink>
I would use Manul's suggestion on adding the email address through an item template
<asp:HyperLink ID="EmailLink" runat="server" Text='Email' NavigateUrl=
"mailto:" + '<%# Eval("yourBoundEmailFieldNameHere") %>'
</asp:HyperLink>
This way you can access the email address and people can see who they will be emailing.
then add this script to the page
$("table tr").dblclick(function () {
var mailto_link = $('a', $(this)).attr('href');
window = window.open(mailto_link, 'emailWindow');
if (window && window.open && !window.closed)
window.close();
});
then remove the code that is adding javascript functions to each row in the grid, because it is no longer needed.
here is a jsfiddle link http://jsfiddle.net/gorrilla/jEX7Y/
You can use command argument to pass the email address, greatly simplifying the logic necessary to retrieve the address.
Change the Command button column to an TemplateField and add a asp:button inside. Then add the attribute CommandArgument to the button.
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="dblClick" runat="server" Text="dblClick"
CommandArgument="<%# ((GridViewRow) Container).RowIndex %>"
CommandName="dblClick" />
</ItemTemplate>
</asp:TemplateField>
Then in the code behind
protected void gvCE_RowCommand(object sender, GridViewCommandEventArgs e)
{
string email = e.CommandArgument;

Categories