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.
Related
Check / Select only one single Radio Button in Rad Grid or Grid View with Paging and any PageSize at Server Side Code behind in C#
My Aim is to maintain user selected asp:RadioButton inside telerik:RadGrid to be selected / checked even with the paging of the grid and with any PageSize accordingly.
The Challenges i'm facing are unable to maintain Unique GroupName for each RadioButton present for each row in Grid. Due to this i have to handle this functionality in code behind.
How ever i tried searching internet for solution which i found some javascript answers with lot of work around which i'm not satisfied with them.
<telerik:RadGrid ID="rgWithPaging" AllowPaging="True" CellSpacing="0" GridLines="None"
AllowSorting="True" runat="server" AutoGenerateColumns="False"
AllowFilteringByColumn="true" EnableLinqExpressions="false"
PagerStyle-PageSizeControlType="RadDropDownList" PagerStyle-AlwaysVisible="true" Visible="true"
OnNeedDataSource="rgWithPaging_NeedDataSource">
...........
<telerik:GridTemplateColumn HeaderText="Check One" HeaderStyle-CssClass="gradient" AllowFiltering="false" HeaderStyle-Width="10%">
<ItemTemplate>
<asp:RadioButton ID="rbWPFileName" runat="server"/>
</ItemTemplate>
</telerik:GridTemplateColumn>
...........
</telerik:RadGrid>
The Answer i came up with server side code behind is as given below:
<telerik:RadGrid ID="rgWithPaging" AllowPaging="True" CellSpacing="0" GridLines="None"
AllowSorting="True" runat="server" AutoGenerateColumns="False"
AllowFilteringByColumn="true" EnableLinqExpressions="false"
PagerStyle-PageSizeControlType="RadDropDownList" PagerStyle-AlwaysVisible="true" Visible="true"
OnNeedDataSource="rgWithPaging_NeedDataSource" OnDataBound="rgWithPaging_OnDataBound">
...........
<telerik:GridTemplateColumn HeaderText="Check One" HeaderStyle-CssClass="gradient" AllowFiltering="false" HeaderStyle-Width="10%">
<ItemTemplate>
<asp:RadioButton ID="rbWPFileName" runat="server" AutoPostBack="true" OnCheckedChanged="rbWPFileName_OnCheckedChanged"/>
</ItemTemplate>
</telerik:GridTemplateColumn>
...........
</telerik:RadGrid>
now in code behind to achieve this we need only two events
OnCheckedChanged="rbWPFileName_OnCheckedChanged" and
OnDataBound="rgWithPaging_OnDataBound"
In code behind:
protected void rbWPFileName_OnCheckedChanged(object sender, EventArgs e)
{
var rbtnSelected = sender as RadioButton;
if (rbtnSelected == null) return;
foreach (GridDataItem item in rgWithPaging.Items)
{
var radFileName = (RadioButton)item.FindControl("rbWPFileName");
if (radFileName == null) return;
radFileName.Checked = rbtnSelected.ClientID == radFileName.ClientID;
if (radFileName.Checked)
{
var position = (rgWithPaging.PageSize*rgWithPaging.CurrentPageIndex) + item.ItemIndex;
Session["Position"] = position;
}
}
}
protected void rgWithPaging_OnDataBound(object sender, EventArgs e)
{
if (Session["Position"] == null) return;
var position = (int)Session["Position"];
var pageIndex = position / rgWithPaging.PageSize;
var itemIndex = position%rgWithPaging.PageSize;
if (pageIndex == rgWithPaging.CurrentPageIndex)
{
foreach (GridDataItem item in rgWithPaging.Items)
{
var radFileName = (RadioButton)item.FindControl("rbWPFileName");
if (radFileName == null) return;
radFileName.Checked = itemIndex == item.ItemIndex;
}
}
}
that's it task done!!! enjoy..:-)
I want to display data in gridview based on check box selection from another grid view. The given below code getting values into from first gridview based on check box selection. I want to bind that values into second grid. Help me to find a proper solution. Thank you.
Code :
protected void btnAssign_Click(object sender, EventArgs e)
{
foreach (GridViewRow row in GridView1.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
CheckBox chkRow = (row.Cells[2].FindControl("CheckBox1") as CheckBox);
if (chkRow.Checked)
{
string[] EmpId = new string[] { row.Cells[0].Text };
string[] EmpName = new string[] { row.Cells[1].Text};
// I want to display emp id and emp name on gridview 2 based on check box selection. How can I do. Help me to find a proper solution
GridView2.DataSource = EmpId;
GridView2.DataBind();
}
}
}
}
ASPX:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="EmployeeID" HeaderText="Employee ID" ReadOnly="True" SortExpression="EmployeeID" />
<asp:BoundField DataField="FirstName" HeaderText="Employee Name" ReadOnly="True" SortExpression="FirstName" />
<asp:TemplateField HeaderText="Select" SortExpression="Select">
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:GridView ID="GridView2" runat="server"> </asp:GridView>
The given below image is showing data in grid view based on drop-down selection. After that I want to select some rows and click assign then I have to display the selected rows in new gridview.
Image :
If you don't already have a strong type defined to represent your selected Employee, you could create a Dictionary to store your selected employees. Upon completing your iteration over GridView1's rows to get the selected employees, you could use the dictionary as the datasource for GridView2 and bind to the Key and Value of each entry.
protected void btnAssign_Click(object sender, EventArgs e)
{
Dictionary<int, string> selectedEmployees = new Dictionary<int, string>();
foreach (GridViewRow row in GridView1.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
CheckBox chkRow = (row.Cells[2].FindControl("CheckBox1") as CheckBox);
if (chkRow.Checked)
{
selectedEmployees.Add(int.Parse(row.Cells[0].Text), row.Cells[1].Text);
}
}
}
if (selectedEmployees.Any())
{
gridView2.DataSource = selectedEmployees;
gridView2.DataBind();
}
}
UPDATE: Updated the code to account for the exception that you were receiving with the sample code provided
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.
I want to change the text/value of a cell in certain condition in GridView. I have a cell that return 'P', 'A', 'R' when I bind the Gridview from database. I want to show 'Pending' in case of 'P', 'Approved' in case of 'A' and 'Rejected' in case of 'R' in the dropdown with the update button. I want to change the status of a record.
How can I change the text AND do my required task at the time of Binding of data.
<asp:TemplateColumn>
<HeaderStyle CssClass="bgB white p5 b treb ttu w10" />
<HeaderTemplate>
<asp:Label ID="lblstatus" runat="server" Text="Status"></asp:Label>
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="lblrmastatus" runat="server" Text='<%# Bind("RMA_STATUS") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateColumn>
A way to solve this is to handle the RowDataBound event. It is raised once per row (also header and footer rows, so you need to filter for rows of type DataRow). You can use it to adjust the data that are displayed or the way they are displayed. Also you can set the values of a DropDown in the event. See the link for a sample.
In order to add the DropDown-column to the GridView, use a TemplateColumn and put the DropDown into the ItemTemplate. Access the corresponding cell in the RowDataBound event handler. Use the FindControl method to retrieve the DropDown control and set its values.
The following sample shows how to set the Label and the DropDownList programmatically:
GridView
The GridView shows both the original status and a new status with the long text, a DropDownList and a command column to update the data.
<asp:GridView ID="gdv" runat="server"
OnRowDataBound="gdv_RowDataBound" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="RMAStatus" HeaderText="Original RMA Status" />
<asp:TemplateField HeaderText="Adjusted RMA Status">
<ItemTemplate>
<asp:Label ID="lblStatus" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="New Status">
<ItemTemplate>
<asp:DropDownList ID="ddlStatus" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowEditButton="true" />
</Columns>
</asp:GridView>
Code-behind
In Code-behind, I've defined a class called DataClass that contains the data (you can also use a DataTable, but for the sample it was easier to use a class to generate some data). Also, a dictionary contains the mappings from the short status to the long text.
In Page_Load, the dictionary is set up and if it is no PostBack, the data are bound.
Finally, in gdv_RowDataBound, the label is set for each row and the DropDownList is initialized. Please note that the Label and the DropDownList for the row are retrieved by using FindControl.
public class DataClass
{
public string RMAStatus { get; set; }
}
private readonly Dictionary<string, string> rmaStatusMappings = new Dictionary<string, string>();
protected void Page_Load(object sender, EventArgs e)
{
rmaStatusMappings.Add("R", "Rejected");
rmaStatusMappings.Add("A", "Approved");
rmaStatusMappings.Add("P", "Pending");
if (!IsPostBack)
{
var data = new DataClass[] {
new DataClass() { RMAStatus = "P" },
new DataClass() { RMAStatus = "A" },
new DataClass() { RMAStatus = "R" },
new DataClass() { RMAStatus = "P" },
};
gdv.DataSource = data;
gdv.DataBind();
}
}
protected void gdv_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var rowStatus = ((DataClass)e.Row.DataItem).RMAStatus;
// Set label to long status
var lblStatus = e.Row.Cells[1].FindControl("lblStatus") as Label;
if (lblStatus != null)
lblStatus.Text = rmaStatusMappings[rowStatus];
// Set drop down items
var ddlStatus = e.Row.Cells[2].FindControl("ddlStatus") as DropDownList;
if (ddlStatus != null)
{
ddlStatus.DataTextField = "Value";
ddlStatus.DataValueField = "Key";
ddlStatus.DataSource = rmaStatusMappings;
ddlStatus.DataBind();
ddlStatus.SelectedValue = rowStatus;
}
}
}
Let me know in the comments if you have any questions.
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; }
}