Data Lost from UserControl when I use RadGrid EditForm with UserControl - c#

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.

Related

DropDownList can't see the control in code behind

I have two drop downs, dependant on the end users area of business I'm wanting to disable one and hide it.
The ddls are in a gridview & I'm getting 'object reference not set to an instance of an object' & the ddl being null, I tested this outside of a gridview and it worked fine.
aspx
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" CellPadding="4" DataKeyNames="RowID, Status,Code"
OnSelectedIndexChanged="GridView1_SelectedIndexChanged" ForeColor="#333333" Font-Names="Calibri" PageSize="10" GridLines="None" ShowFooter="True">
<AlternatingRowStyle BackColor="White" />
<Columns>
<asp:BoundField ItemStyle-Width="50px" DataField="Person" HeaderText="Person" ItemStyle-HorizontalAlign="center" />
<asp:BoundField ItemStyle-Width="100px" DataField="Code" HeaderText="Client Code" ItemStyle-HorizontalAlign="center" />
<asp:BoundField ItemStyle-Width="300px" DataField="ClientName" HeaderText="Client" />
<asp:BoundField ItemStyle-Width="150px" DataField="Status" HeaderText="Status Tracker" />
<asp:TemplateField HeaderText="Update Status" ItemStyle-HorizontalAlign="center">
<ItemTemplate>
<asp:DropDownList ID="ddlClientStatus" Name="ddlClientStatus" runat="server" AutoPostBack="True" onselectedindexchanged="StatusSelected" >
<asp:ListItem Selected="True" Value=""></asp:ListItem>
<asp:ListItem Value="Val1">1</asp:ListItem>
<asp:ListItem Value="Val2">2</asp:ListItem>
<asp:ListItem Value="Val3">3</asp:ListItem>
<asp:ListItem Value="Val4">4</asp:ListItem>
<asp:ListItem Value="Val5">5</asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
<ItemStyle Width="150px"/>
</asp:TemplateField>
<asp:TemplateField HeaderText="Update Status" ItemStyle-HorizontalAlign="center">
<ItemTemplate>
<asp:DropDownList ID="ddlClientStatusPL" Name="ddlClientStatusPL" runat="server" AutoPostBack="True" onselectedindexchanged="StatusSelected" >
<asp:ListItem Selected="True" Value=""></asp:ListItem>
<asp:ListItem Value="Val6">6</asp:ListItem>
<asp:ListItem Value="Val7">7</asp:ListItem>
<asp:ListItem Value="Val8">8</asp:ListItem>
<asp:ListItem Value="Val9">9</asp:ListItem>
<asp:ListItem Value="Val10">10</asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
<ItemStyle Width="150px"/>
</asp:TemplateField>
</Columns>
cs
namespace Dashboard
{
public partial class StatusTracker : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
role = Request.QueryString["role"];
if (role == "Sales")
{
ddlClientStatus.Enabled = false;
ddlClientStatus.Visible = false;
ddlClientStatusPL.Enabled = true;
}
else
{
ddlClientStatus.Enabled = true;
ddlClientStatusPL.Enabled = false;
ddlClientStatusPL.Visible = false;
}
}
}
}
I've also tried the below with no joy, still a null for the ddls.
DropDownList ddlClientStatus = (DropDownList)GridView1.FindControl("ddlClientStatus");
DropDownList ddlClientStatusPL = (DropDownList)GridView1.FindControl("ddlClientStatusPL");
I feel like I'm missing something really obvious.... Any help/pointers would be much appreciated!
Since you are creating your drop down lists inside of a gridview, you need to wait until the gridview has rows populated.
When this happens, you can hook into gridview's RowDatabound event to set the visible and/or display properties of your dropdown lists.
<asp:GridView ID="dataGridView" runat="server" AutoGenerateColumns="false" CssClass= "table table-striped table-bordered table-condensed" OnRowDataBound="GridView1_RowDataBound">
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e) handles
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList ddlClientStatus = (DropDownList)e.Row.FindControl("ddlClientStatus");
DropDownList ddlClientStatusPL =(DropDownList)e.Row.FindControl("ddlClientStatusPL");
ddlClientStatus.Visible = //do your logic to determine which should be visible / enabled
ddlClientStatusPL.Visible = !ddlClientStatus.visible
}
}
Let me try to solve your problem by replicating similar scenario. In this case, there is a GridView in the page which shows data of some persons. Each person have firstname, lastname and role.
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Role { get; set; }
}
Following is the code from .aspx.
<asp:GridView ID="dataGridView" runat="server" AutoGenerateColumns="false" CssClass= "table table-striped table-bordered table-condensed">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="First name" />
<asp:BoundField DataField="LastName" HeaderText="Last name" />
<asp:TemplateField HeaderText="Role">
<ItemTemplate>
<asp:DropDownList ID="ddlRoles" runat="server">
<asp:ListItem Value="Admin" Text="Admin"></asp:ListItem>
<asp:ListItem Value="SuperAdmin" Text="Super Admin"></asp:ListItem>
<asp:ListItem Value="Lead" Text="Lead" ></asp:ListItem>
<asp:ListItem Value="Developer" Text="Developer" ></asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
As you can see the grid view has two BoundFields and on TemplateField and the TemplateFields has a dropdownlist in it. The dropdownlist has 4 items added to it.
Following is the code in code behind which load persons data in the GridView.
public partial class _Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
PopulateGridView();
}
}
private void PopulateGridView()
{
var persons = new List<Person>();
persons.Add(new Person { FirstName = "Blithe", LastName = "Taig", Role = "Developer" });
persons.Add(new Person { FirstName = "Ewan", LastName = "Critoph", Role = "SuperAdmin" });
persons.Add(new Person { FirstName = "Hyatt", LastName = "Atkinson", Role = "Lead" });
persons.Add(new Person { FirstName = "Paloma", LastName = "Bauldry", Role = "Lead" });
persons.Add(new Person { FirstName = "Eldon", LastName = "Lambert", Role = "Developer" });
persons.Add(new Person { FirstName = "Ethyl", LastName = "Mugford", Role = "Lead" });
persons.Add(new Person { FirstName = "Leupold", LastName = "Longmuir", Role = "SuperAdmin" });
dataGridView.DataSource = persons;
dataGridView.DataBind();
}
}
With the above code, the Gridview is populated as following.
You can see that all the persons have role Admin selected in the gridview while they have different value set for Role in the code above. the dropdown list in the GridView Items do not get the values from the GridView DataSource by default. The values of DDL in each row need to be set by code.
For this I used RowDataBound event of the GridView. First I added OnRowDataBound="dataGridView_RowDataBound" attirbute in GridView inside aspx.
<asp:GridView ID="dataGridView" runat="server" AutoGenerateColumns="false" OnRowDataBound="dataGridView_RowDataBound" CssClass= "table table-striped table-bordered table-condensed">
And also created this event handler in the aspx.cs.
protected void dataGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
var dataItem = e.Row.DataItem as Person;
if(dataItem != null)
{
var ddlRoles = (DropDownList)e.Row.FindControl("ddlRoles");
if(ddlRoles != null)
{
ddlRoles.SelectedValue = dataItem.Role;
}
}
}
With this change, the Role column in the GridView has now proper role selected in each row.
You can see in the code of dataGridView_RowDataBound how dropDown list is retrieved from the Row of Gridview by doing (DropDownList)e.Row.FindControl("ddlRoles").
Now coming to the similar feature you are implementing. There will be a query string parameter name role. And the gridview should have all the dropdownlist disabled which has that role selected.
Following is the code I wrote for disabling the dropdown.
private void DisableRole(string role)
{
// Loop thru GridView Rows.
foreach(GridViewRow row in dataGridView.Rows)
{
// Try to find dropdownlist with id=ddlRoles from each row.
var ddlRole = (DropDownList)row.FindControl("ddlRoles");
// Disabled the dropdownlist if it is found the it has matching role selected
if(ddlRole != null && ddlRole.SelectedItem.Value == role)
{
ddlRole.Enabled = false;
}
}
}
Then called this method from Page_Load.
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
PopulateGridView();
}
var role = Request.QueryString["role"];
if(!string.IsNullOrEmpty(role))
{
DisableRole(role);
}
}
With this change, when I browse URL http://localhost:53384/Default?role=Lead, the dropdowns with Lead selected in them are disabled.
In the code above I am iterating thru the Rows collection of GridView and finding Dropdownlist inside each row and trying to disable them.
The scenario I explained might be little different than yours. What I am trying to demonstrate is, if you need to access any control which is placed inside ItemTemplate of a GridView, you can only access it via GridViewRow. And you can loop thru the GridView.Rows collection wherever you need to.
I hope this will resole your doubts and help you resolve your issue.

C# asp.net checkbox not firing when unchecked

I have found this question a few places but no solutions...
I have a checkbox in a gridview:
<asp:TemplateField HeaderText="Closed?">
<ItemTemplate >
<asp:CheckBox ID="Status_CB" runat="server" AutoPostBack="true"
OnCheckedChanged="Status_CB_CheckedChanged"
EnableViewState="true" ViewStateMode="Enabled"
Checked='<%# Convert.ToString(Eval("cStatus")) == "1" ? true : false %>'/>
</ItemTemplate>
</asp:TemplateField>
codebehind:
protected void Page_Load(object sender, EventArgs e) {
if (!int.TryParse(Session["FacilityID"].ToString(), out FId)) {
FId = 0;
}
if (!Page.IsPostBack) {
if (!string.IsNullOrEmpty(Request.QueryString.Get("WorkCenter"))) {
wc = Request.QueryString.Get("WorkCenter");
WorkcenterHeader.InnerText = wc + " Schedule ";
HiddenWorkCenter.Value = c;
}
if (!SQLHasData()) {
SavePrioritiesToSQL();
}
BindGrid();
}
}
protected void Status_CB_CheckedChanged(object sender, EventArgs e) {
CheckBox cb = (CheckBox)sender;
GridViewRow row = (GridViewRow) cb.Parent.Parent;
}
When i check the box originally, it works. When i uncheck it, the breakpoint i have on the first line of Status_CB_CheckedChanged does not fire at all.
What am i missing any one know?
UPDATE - here is the table, it is nested. i wonder if that is the reason it will not call the postback on uncheck...
UPDATE - ok i gave up, this must be a bug with nested gridview in asp so if you have a nested gridview, i recommend not using checkboxes. I switched mine to a text field of the cStatus "open" or "closed" and use a button with a command argument that is the row index:
<asp:GridView ID="JobInfo_GV" runat="server" AutoGenerateColumns="false" CssClass="ChildGrid2" OnRowCommand="JobInfo_GV_RowCommand">
<asp:BoundField DataField="cStatus" HeaderText="Status" ReadOnly="True" HeaderStyle-CssClass="center-row" ItemStyle-CssClass="center-row"/>
<asp:TemplateField HeaderText="Update">
<ItemTemplate >
<asp:Button id="UpdateClosed" commandname="Select" buttontype="button" Text="ToggleStatus" runat="server" CommandArgument='<%# Container.DataItemIndex %>'/>
</ItemTemplate>
</asp:TemplateField>
then the C#:
protected void JobInfo_GV_RowCommand(object sender, GridViewCommandEventArgs e) {
var grid = (GridView)sender;
var errorMessage = string.Empty;
if (grid != null) {
int index = 0;
if (int.TryParse(e.CommandArgument.ToString(), out index) ){
GridViewRow row = grid.Rows[index];
I just created a project and reused your code as part of it.
It works as you expect:
Note you need to set AutoPostBack="true" for the Checkbox control
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1.Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="GV" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="Name" HeaderText="Name">
</asp:BoundField>
<asp:TemplateField HeaderText="Closed?">
<ItemTemplate>
<asp:CheckBox ID="Status_CB" runat="server" AutoPostBack="true"
OnCheckedChanged="Status_CB_CheckedChanged"
EnableViewState="true" ViewStateMode="Enabled"
Checked='<%# Convert.ToString(Eval("cStatus")) == "1" ? true : false %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</form>
</body>
</html>
And the Code behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication1
{
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
BindGrid();
}
public class DataS
{
public int cStatus { get; set; }
public string Name { get; set; }
}
private void BindGrid()
{
List<DataS> list = new List<DataS>() { new DataS() { Name = "Name1", cStatus = 1 }, new DataS() { Name = "Name2", cStatus = 1 }, new DataS() { Name = "Name3", cStatus = 0 } };
GV.DataSource = list;
GV.DataBind();
}
protected void Status_CB_CheckedChanged(object sender, EventArgs e)
{
CheckBox cb = (CheckBox)sender;
GridViewRow row = (GridViewRow)cb.Parent.Parent;
}
}
}

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);
}
}

asp:GridView HYPERLINKFIELD - asp code inside datanavigateurlformatstring

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; }
}

Getting index of a gridview when hyperlinkfield is clicked

I have a web app(ASP.NET 2.0 using C#) that I am working on. In it, I have a gridview with a hyperlinkfield on a page(My_Page.aspx). When the Hyperlinkfield is clicked, it shows details on the same page.
<asp:HyperLinkField DataNavigateUrlFields="ID"
DataNavigateUrlFormatString="My_Page.aspx?id={0}"
DataTextField="NAME"
HeaderText="Item1"
SortExpression="NAME" />
I want to know how to find the Index of the row in which the Hyperlink is clicked, because I want to change its style, so that the user knows which row was clicked.
OR
How would I change the style of it when the user clicks hyperlink in the gridview.
Thank you.
In your example, the "index" or rather "id" of the hyperlink that was clicked will be in Request.QueryString["id"]
You could compare the ID from the querystring with the ID of the row you are binding to in the RowDataBound event.
Alternatively you could use a <%# DataBinder.Eval %> in your aspx to set the style based upon the ID field and the query string.
EDIT: Code Sample, try adding this to your code behind.
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if(Request.QueryString["id"] != null &&
Request.QueryString["id"] == DataBinder.Eval(e.Row.DataItem, "id").ToString())
{
e.Row.Style.Add("font-weight", "bold");
}
}
}
It is an sample which when you select a row on Gridview child of selected node are shown in the same gridview:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
LocationIDHiddenField.Value = Request.QueryString["LocationID"];
}
if (LocationIDHiddenField.Value != null && LocationIDHiddenField.Value != string.Empty)
LoadLocationParents();
}
private void LoadLocationParents()
{
long locationID = Convert.ToInt64(LocationIDHiddenField.Value);
bool IsCurrent = true;
HyperLink parent;
Label seperator;
do
{
Basic.Location.LocationProperties location = Basic.Location.LocationLoader.GetLocationProperties(locationID);
parent = new HyperLink();
seperator = new Label();
if (!IsCurrent)
parent.NavigateUrl = string.Format("LOCATIONLOV.aspx?LocationID={0}", location.LocationID);
IsCurrent = false;
parent.Text = location.LocationTitle;
seperator.Text = " > ";
ParentsPanel.Controls.AddAt(0, parent);
ParentsPanel.Controls.AddAt(0, seperator);
locationID = location.ParentID;
}
while (locationID != 0);
parent = new HyperLink();
parent.NavigateUrl = "LOCATIONLOV.aspx";
parent.Text = "upper nodes";
ParentsPanel.Controls.AddAt(0, parent);
}
GridView
<asp:GridView ID="ChildsGridView" runat="server" AutoGenerateColumns="False" DataKeyNames="LocationID"
DataSourceID="ChildsObjectDataSource" Width="570px" AllowPaging="True">
<Columns>
<asp:TemplateField>
<HeaderTemplate>
</HeaderTemplate>
<ItemStyle Width="20px" />
<ItemTemplate>
<a onclick="if ('<%# Eval("ChildCount") %>' == 'False') return false;" href='<%# Eval("LocationID", "LOCATIONLOV.aspx?LocationID={0}") %>' ><asp:Image ID="GridLocationLov" runat="server" ToolTip="Expand" SkinID="LOVChilds" /></a>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Title" SortExpression="LocationTitleType">
<ItemTemplate>
<span class="LOVSelectText" onclick="LOCATIONID = '<%# Eval("LocationID") %>'; LOCATIONTITLE = <%= ConfirmTextBox.ClientID %>.value = '<%# Eval("LocationTitle") %>';ChangeSelectedRow(this);">
<%# Eval("LocationTitleType")%>
</span>
</ItemTemplate>
<HeaderTemplate>
<asp:Label ID="GridHeadLabel" runat="server" OnLoad="GridHeadLabel_Load"></asp:Label>
</HeaderTemplate>
</asp:TemplateField>
</Columns>
<EmptyDataTemplate>
NO CHild
</EmptyDataTemplate>
</asp:GridView>
DataSource
<asp:ObjectDataSource ID="ChildsObjectDataSource" runat="server" OldValuesParameterFormatString="original_{0}"
SelectMethod="Retrive" TypeName="BASIC.LOCATIONLOV.LOCATIONLOVLoader">
<SelectParameters>
<asp:ControlParameter ControlID="LocationIDHiddenField" Name="ParentID" PropertyName="Value"
Type="Int64" />
<asp:Parameter DefaultValue="LocationTitle" Name="SortExpression" Type="String" />
</SelectParameters>
</asp:ObjectDataSource>
<asp:HiddenField ID="LocationIDHiddenField" runat="server" />
JavaScript
function ChangeSelectedRow(sender)
{
if (SelectedRow != null)
SelectedRow.style.backgroundColor = OriginalColor;
SelectedRow = sender.parentElement.parentElement;
OriginalColor = SelectedRow.style.backgroundColor;
SelectedRow.style.backgroundColor = 'red';
}

Categories