I have two tables relevant to this question...
tblCellTechnology
CellTechnologyID, PK
Description
CellName
tblActionSchedule
ActionID, PK
ActionPhase
ActionPeriod
CellTechnology, FK
I have a bulk edit grid view with text boxes displaying the ActionID, Phase, Period and a dropdownlist linked directly to the CellTechnologyID from tblCellTechnology (as per image). I also have another textbox displaying the cell name based on the value in tblScheduleAction.CellTechnologyID (ActionDescription is pulled from another table).
How can I get the selected value from the ddl and write that to tblScheduleAction.CellTechnologyID? When I hard add a CellTechnologyID to tblScheduleActionID, the cellname textbox displays the correct value. I just need to be able to store the ddl.SelectedValue to tblScheduleAction.CellTechnologyID. I am using masterpages and sqldatasources to handle the inserting/updating/deleting of records.
I want the celltechnologyid column in the bottom gridview to display the list of potential celltechnologyid, it does as it is directly linked to that column from the top grid view, the selected value should also be stored in tblScheduleAction.CellTechnologyID. The cellname column should display the respective cellname.
As they say, a picture is worth a thousand words... http://imgur.com/21FjOzh
By nested gridviews, I assume you are referring to a child gridview inside each parent gridview row. Getting values of child gridview controls is pretty easy.
How can I get the selected value from the ddl and write that to tblScheduleAction.CellTechnologyID?
You use FindControl to find childgridview in say a foreach loop on your save records
You would then use find control to find the dropdownlists & save to your database
Check working example (Aspx)
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="NestedGridviews.aspx.cs" Inherits="WebApplication1.NestedGridviews" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="gvParent" runat="server" AutoGenerateColumns="False"
DataKeyNames="CategoryID" DataSourceID="sdsParentGrid"
onrowdatabound="GridView1_RowDataBound">
<Columns>
<asp:BoundField DataField="CategoryID" HeaderText="CategoryID"
InsertVisible="False" ReadOnly="True" SortExpression="CategoryID" />
<asp:BoundField DataField="CategoryName" HeaderText="CategoryName"
SortExpression="CategoryName" />
<asp:BoundField DataField="Description" HeaderText="Description"
SortExpression="Description" />
<asp:TemplateField>
<ItemTemplate>
<asp:GridView ID="gvChildGrid" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="sdsChildGrid">
<Columns>
<asp:BoundField DataField="ProductID" HeaderText="ProductID"
InsertVisible="False" ReadOnly="True" SortExpression="ProductID" />
<asp:BoundField DataField="ProductName" HeaderText="ProductName"
SortExpression="ProductName" />
<asp:BoundField DataField="SupplierID" HeaderText="SupplierID"
SortExpression="SupplierID" />
<asp:BoundField DataField="CategoryID" HeaderText="CategoryID"
SortExpression="CategoryID" />
<asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
SortExpression="Discontinued" />
<asp:TemplateField HeaderText="My DropDown Column">
<ItemTemplate>
<asp:DropDownList ID="ddlTest" runat="server">
<asp:ListItem>Potatoes</asp:ListItem>
<asp:ListItem>Tomatoes</asp:ListItem>
<asp:ListItem>Mangoes</asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="sdsChildGrid" runat="server"
ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT [ProductID], [ProductName], [SupplierID], [CategoryID], [Discontinued] FROM [Alphabetical list of products] WHERE ([CategoryID] = #CategoryID)">
<SelectParameters>
<asp:Parameter Name="CategoryID" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="sdsParentGrid" runat="server"
ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT [CategoryID], [CategoryName], [Description] FROM [Categories] ORDER BY [CategoryName]">
</asp:SqlDataSource>
</div>
<asp:Button ID="btnSave" runat="server" onclick="btnSave_Click"
Text="Save to Database" />
</form>
</body>
</html>
Codebehind
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 NestedGridviews : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
GridView gvChild = e.Row.FindControl("gvChildGrid") as GridView;
SqlDataSource sdsTemp = e.Row.FindControl("sdsChildGrid") as SqlDataSource;
if (sdsTemp!=null)
{
sdsTemp.SelectParameters[0].DefaultValue = gvParent.DataKeys[e.Row.RowIndex]["CategoryID"].ToString();
if (gvChild != null)
{
gvChild.DataBind();
}
}
}
}
protected void btnSave_Click(object sender, EventArgs e)
{
foreach (GridViewRow growParent in gvParent.Rows)
{
// Find child gridview for each row
GridView gvChild = growParent.FindControl("gvChildGrid") as GridView;
if (gvChild != null)
{
// use a foreach loop to find your control
foreach (GridViewRow growChild in gvChild.Rows)
{
DropDownList ddlTemp = growChild.FindControl("ddlTest") as DropDownList;
if (ddlTemp != null)
{
Response.Write(ddlTemp.SelectedValue.ToString());
}
}
}
}
}
}
}
Related
Q> I want to show a GridView button's text as hard coded and a event to fire on button click. How to achieve this ?
Till now I've been able to come this far
But I want to show button text as Read or Delete not the value in the Read/Delete column.
The code I've used
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="MID" DataSourceID="inbox" EnableModelValidation="True"
onselectedindexchanged="GridView1_SelectedIndexChanged">
<Columns>
<asp:ButtonField ButtonType="Button" DataTextField="MID" HeaderText="Read"
Text="Read" />
<asp:BoundField DataField="MID" HeaderText="MID" InsertVisible="False"
ReadOnly="True" SortExpression="MID" />
<asp:BoundField DataField="sender" HeaderText="sender"
SortExpression="sender" />
<asp:BoundField DataField="subject" HeaderText="subject"
SortExpression="subject" />
<asp:BoundField DataField="on" HeaderText="on" SortExpression="on" />
<asp:ButtonField ButtonType="Button" DataTextField="MID" HeaderText="Delete"
Text="Delete" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="inbox" runat="server"
ConnectionString="<%$ ConnectionStrings:connectionString %>"
SelectCommand="SELECT [MID], [sender], [subject], [on] FROM [mail]">
</asp:SqlDataSource>
If you want the text to appear as "Delete" or "Read", then simply don't set the DataTextField property to use the MID property of the result and instead set the CommandName property as so:
<asp:ButtonField ButtonType="Button" CommandName='<%#Eval("MMID")%>' HeaderText="Delete"
Text="Delete" />
As far as handling the OnClick event of the buttons, you can handle the OnRowCommand event on the GridView as so:
<asp:GridView ID="GridView1" runat="server" OnRowCommand="GridView_RowCommand" AutoGenerateColumns="False"
Now add the code behind:
protected void GridView_RowCommand(Object sender, GridViewCommandEventArgs e)
{
string MMID = e.CommandName;
if( (e.CommandSource as ButtonField).Text=="Delete")
{
//oh, I should delete this MMID
}
}
UPDATE
Above code does not work. ButtonField is as useful as nipples are to men. Instead use an ItemTemplateField as so:
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btn" runat="server" CommandName="Delete" CommandArgument='<%#Eval("MID") %>'
Text="Delete" />
</ItemTemplate>
</asp:TemplateField>
Then the GridView_RowCommand becomes this:
protected void GridView_RowCommand(Object sender, GridViewCommandEventArgs e)
{
string mid = e.CommandArgument.ToString();
// If multiple buttons are used in a GridView control, use the
// CommandName property to determine which button was clicked.
if (e.CommandName == "Delete")
{
}
}
i have a checkbox in a template field of a gridview and i want to get the id of the record at a checkbox tick. how do i do it? i am doing asp.net and also by using datakeynames instead, my gridview also shows the datakeynames persID column. why?
my code:
<asp:GridView ID="GridViewHostelMember" runat="server" DataKeyNames="_PersID" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="_PersID" HeaderText="_PersID" />
<asp:BoundField DataField="FirstName" HeaderText="First Name" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="DOB" HeaderText="DOB" />
<asp:BoundField DataField="FatherName" HeaderText="FatherName" />
<asp:BoundField DataField="Type" HeaderText="Type" />
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="CheckBoxSelect" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
protected void Button1_Click(object sender, EventArgs e)
{
foreach (GridViewRow item in this.GridViewHostelMember.Rows)
{
CheckBox chbTemp = item.FindControl("CheckBoxSelect") as CheckBox;
if (chbTemp != null)
{
if (chbTemp.Checked)
{
Label1.Text = item.Cells[0].Text;
}
}
}
}
_PersID is showing because autogeneratecolumns is set to true; if true, it shows all columns. To hide, set to false, and explicitly add the columns to the grid.
For the first part, at checkbox tick, you would need to set AutoPostBack="true" on the checkbox, which posts back, and then you can check the data key for the current row of the grid.
Reference -
my gridview also shows the datakeynames persID column. why?
true to automatically create bound fields for each field in the data
source; otherwise, false. The default is true.
It should be like below..
<asp:GridView ID="GridViewHostelMember" autogeneratecolumns="False"
runat="server" DataKeyNames="_PersID">
i want to get the id of the record at a checkbox tick. how do i do it?
Sample Code
protected void CheckBox_Checked(object sender, EventArgs e)
{
CheckBox c = (CheckBox)sender;
//c.ValidationGroup is your ID
}
Sample HTML
<asp:GridView ID="ed" runat="server" OnRowCommand="GridView_RowCommand">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="chk" runat="server" AutoPostBack="true" ValidationGroup='<%#Eval("ID") %>' OnCheckedChanged="CheckBox_Checked" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
I am using ASP.NET 4 and MVC and trying to add code to handle the "select" link. Once the user selects the row, I need to go display a new page with more detail. I have tried to capture the rowcommand but I never hit a the breakpoint. This is my current GridView code for the first page -
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<ValidationPortal.Models.Contact>>" %>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<form id="form1" runat="server">
<h2>Index</h2>
<p>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="Id" DataSourceID="SqlDataSource1">
<Columns>
<asp:CommandField ShowSelectButton="True" />
<asp:BoundField DataField="Id" HeaderText="Id" InsertVisible="False"
ReadOnly="True" SortExpression="Id" />
<asp:BoundField DataField="FirstName" HeaderText="FirstName"
SortExpression="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName"
SortExpression="LastName" />
<asp:BoundField DataField="Phone" HeaderText="Phone" SortExpression="Phone" />
<asp:BoundField DataField="Email" HeaderText="Email" SortExpression="Email" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
SelectCommand="SELECT * FROM [Contacts]"></asp:SqlDataSource>
</p>
</form>
</asp:Content>
What do I need to add to make this work?
I think you need to specify an OnSelectedIndexChanged event in your grid markup. Your event would probably just redirect to your details page with the ID of the selected item. It would look something like this:
Grid:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="Id" DataSourceID="SqlDataSource1"
OnSelectedIndexChanged="SelectEvent">
// rest of grid definitions
</asp:GridView>
C#:
protected void SelectEvent(object sender, EventArgs e)
{
if (GridView1.SelectedIndex >= 0)
Response.Redirect("yourpage.aspx?itemid=" + (int)GridView1.SelectedValue);
}
Personally, for what you are doing I would skip the select command and create an item template with a link to your url, as shown here
Try this way
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Select")
{
// Do something
}
}
If you dont want to using the row command or you want to fire the rowcommand explicitly then use this following segment of code
int GridView1TotalCount = GridView1.Rows.Count;
int r = Convert.ToInt32(dslno)-1;
if (r != -1)
{
if (GridView1TotalCount > r)
{
GridViewRow thisGridView1 = GridView1.Rows[r];
ClientScript.GetPostBackClientHyperlink(this.GridView1, "Select$" + thisGvEmpMaster.RowIndex);
// Do something here you have datakey like
int dkkey = Convert.ToString(GridView1.DataKeys[thisGridView1.RowIndex].Value);
}
}
I have a GridView in an update panel.
The GridView is styled so that each alternate row is a different colour.
When I change page on the GridView it loses the alternate row colouring. All other styles are maintained.
If I remove the update panel the GridView keeps the alternate row colouring after changing page.
Does anyone have any idea on what may be causing this or how to fix it?
Thanks,
Neil
EDIT:
Here is the aspx code
<div id="active-logbooks" class="tab-content clearfix">
<div class="left-column">
<asp:MultiView runat="server" ID="mlvLogbooks" >
<asp:View runat="server" ID="vActiveLogbooks">
<asp:GridView PagerSettings-Mode="NextPrevious" PagerSettings-Position="Top" PagerSettings-NextPageImageUrl="~/img/right-arrow.png" PagerSettings-PreviousPageImageUrl="~/img/left-arrow.png" AllowPaging="true" runat="server" ID="gvActiveLogbooks" PageSize="5" AutoGenerateColumns="false" CssClass="lesson stripe-me" OnRowDataBound="gvActiveLogbooks_RowDataBound" OnPageIndexChanging="gvActiveLogbooks_PageIndexChanging">
<Columns>
<asp:BoundField HeaderText="Logbook number" DataField="LogbookNumber" ItemStyle-CssClass="border" ItemStyle-Width="100" />
<asp:BoundField HeaderText="Origin" DataField="Origin" ItemStyle-CssClass="border" ItemStyle-Width="100" />
<asp:BoundField HeaderText="Order Reference" DataField="OrderReference" ItemStyle-CssClass="border" ItemStyle-Width="100" />
<asp:TemplateField HeaderText="Transfer Date">
<ItemTemplate>
<asp:Literal runat="server" ID="lblTransferDate" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:HyperLink runat="server" ID="lnkTransferLogbook" CssClass="border" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Previous<asp:Literal runat="server" ID="litBreaker" Text=" |" />
Next
</asp:View>
</asp:MultiView>
</div>
And this is the function that is called when the page change occurs:
protected void gvActiveLogbooks_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
HideShowGridViewPagerLinks(e.NewPageIndex);
gvActiveLogbooks.DataSource = _logbooks;
gvActiveLogbooks.PageIndex = e.NewPageIndex;
gvActiveLogbooks.DataBind();
}
Nowhere on the page is there anything done with colouring the GridView rows
protected void gvActiveLogbooks_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType != DataControlRowType.DataRow)
return;
Literal transferLabel = (Literal)e.Row.Cells[(int)ActiveLogbookGridViewColumns.TransferDate].FindControl("lblTransferDate");
transferLabel.Text = _logbooks[e.Row.RowIndex].TransferDate.ToShortDateString();
HyperLink transferLink = (HyperLink)e.Row.Cells[(int)ActiveLogbookGridViewColumns.TransferLink].FindControl("lnkTransferLogbook");
transferLink.Text = TransferLinkText;
transferLink.NavigateUrl = "TransferLogbooks.aspx?id=" + Guid.NewGuid();
}
I'm guessing that some interaction between your CSS classes and the postback is messing this up. What happens if you switch to the RowStyle and AlternateRowStyle tags (example here), and reference your CSS classes using the CssClass property on those tags?
I have one gridview where I am passing the command argument as gridview row id for the Button I created for every row.
I want to display all the details of that row in the textbox according to the Row clicked.
<asp:GridView ID="gvCategory" runat="server" AutoGenerateColumns="false"
onrowcommand="gvCategory_RowCommand" >
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblCatId" runat="server" Text='<%#Eval("categoryId") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblCatName" runat="server" Text='<%#Eval("categoryName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btnModify" runat="server" Text="Modify" CommandName="Modify" CommandArgument='<%#Eval("categoryId") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code.....
if (e.CommandName == "Modify")
{
int id = Convert.ToInt32(e.CommandArgument);
// I want the value to assgin for the selected row here
// I was previously fetching the data from database according id,but i want this frim the gridview of selected row.
}
I wrote a quick example of how to do what you're trying to do. It works for me.
The Example Solution
Default.aspx
<asp:GridView ID="myGridView" runat="server"
AutoGenerateColumns="False"
DataSourceID="StudentsDS"
DataKeyNames="ID"
OnRowCommand="myGridView_RowCommand"
OnSelectedIndexChanged="myGridView_SelectedIndexChanged">
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" ReadOnly="True"
SortExpression="ID" />
<asp:BoundField DataField="FullName" HeaderText="FullName"
SortExpression="FullName" />
<asp:BoundField DataField="ClassID" HeaderText="ClassID"
SortExpression="ClassID" />
<asp:CommandField ShowSelectButton="True" SelectText="Modify" />
</Columns>
</asp:GridView>
<asp:TextBox ID="txtStudent" runat="server" />
<asp:SqlDataSource ID="StudentsDS" runat="server"
ConnectionString="<%$ ConnectionStrings:Sandbox %>"
SelectCommand="SELECT * FROM Student"
/>
Default.aspx.cs
protected void myGridView_RowCommand(object sender, GridViewCommandEventArgs e) {
if (e.CommandName == "Select") {
// do something here if you want, although not necessary
}
}
protected void myGridView_SelectedIndexChanged(object sender, EventArgs e) {
// show "FullName" field of selected row in textbox
txtStudent.Text = myGridView.SelectedRow.Cells[1].Text;
}
How It Works
Upon clicking "Modify" in a row, the textbox updates to show the FullName field of the selected row.
The important part is that instead of a TemplateField, use a CommandField with ShowSelectButton="True". Then do what you need to do in the SelectedIndexChanged event handler. Note that the SelectText of the CommandField is set to "Modify" as you desired. You can also set the ButtonType property of the CommandField to be button, image, or link.
Making It Better
I would also advise that instead of using a SqlDataSource as I have, you use an ObjectDataSource so that you can do something like
protected void myGridView_SelectedIndexChanged(object sender, EventArgs e) {
MyModelObject o = myGridView.SelectedRow.DataItem as MyModelObject;
txtStudent.Text = o.MyProperty;
}
You may also consider wrapping your GridView in an UpdatePanel to prevent full postbacks / page refreshes.
After you have the lineID, you select that line, and then you have the CategoryID on selected value
int iTheIndexNow = Convert.ToInt32(e.CommandArgument);
// select that line to see it visual as selected, and get the value on next line
gvCategory.SelectedIndex = iTheIndexNow;
// here is your categoryID that
//you can use to open your database with and get the text
gvCategory.SelectedValue // == categoryID
On GridView you must have set your KeyID
<asp:GridView DataKeyNames="categoryId" .... >