nested gridview get parent row - c#

I am using Nested GridViews where each row in the gridview has child gridView.
I am using RowDataBound Event of Parent GridView, to Binding Child GridView.
My Problem is that, how to get Parent GridView's Key on Child gridViews RowDataBound Event.
Below is example code:
<asp:GridView ID="gvParent" DataKeyNames="ID" runat="server" PageSize="1" AllowPaging="true" PagerSettings-Mode="NextPrevious" AutoGenerateColumns="False" SkinID="GVCenter" onrowdatabound="gvParent_RowDataBound">
<Columns>
<asp:BoundField DataField="Name" />
<asp:TemplateField>
<ItemTemplate>
<asp:GridView ID="gvChild" DataKeyNames="ID" runat="server" AutoGenerateColumns="false" ShowHeader="false" OnRowDataBound="gvChild_RowDataBound">
<Columns>
<asp:BoundField DataField="Name" />
</Columns>
</asp:GridView>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Here is the code behind:
protected void gvParent_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
GridView gvChild= (GridView)e.Row.FindControl("gvChild");
gvChild.DataSource = getChildObj();
gvChild.DataBind();
}
}
protected void gvChild_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// Here I need to get the parent gridview Row Key
}
}
Hope the above code explains all the scenario.
Thanks in advance
Sandy

Try this
<asp:GridView ID="gvParent" DataKeyNames="ID" runat="server" PageSize="10" AllowPaging="true"
PagerSettings-Mode="NextPrevious" AutoGenerateColumns="False" OnRowDataBound="gvParent_RowDataBound">
<Columns>
<asp:BoundField DataField="Name" />
<asp:TemplateField>
<ItemTemplate>
<asp:HiddenField ID="HdnID" runat="server" Value='<%# Eval("ID") %>' />
<asp:GridView ID="gvChild" DataKeyNames="ID" runat="server" AutoGenerateColumns="false"
ShowHeader="false" OnRowDataBound="gvChild_RowDataBound">
<Columns>
<asp:BoundField DataField="Name" />
</Columns>
</asp:GridView>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code behind
protected void gvParent_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
GridView gvChild = (GridView)e.Row.FindControl("gvChild");
gvChild.DataSource = GetData();
gvChild.DataBind();
}
}
protected void gvChild_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string ID = ((HiddenField)e.Row.Parent.Parent.Parent.FindControl("HdnID")).Value;
}
}

I don't think you will be able to track it normally, but I would embed ID field into the hidden field and put this hidden field under TemplateField,
<ItemTemplate>
<asp:HiddenField ID="idOfYourHiddenField" runat="server" Value='<%# Eval("ID") %>' />
<asp:GridView ID="gvChild" DataKeyNames="ID" runat="server" AutoGenerateColumns="false" ShowHeader="false" OnRowDataBound="gvChild_RowDataBound">
<Columns>
<asp:BoundField DataField="Name" />
</Columns>
</asp:GridView>
</ItemTemplate>
this way you can get its value by going
gvChild.Parent.FindControl("idOfYourHiddenField");

You Can Access The Parent of Child Gridview with the Parent Property.
You must be Try This:
GridView gvChild = (GridView)e.Row.FindControl("gvChild");
Response.Write(gvChild.Parent);

You have to go 4 steps back and get the parent row like this
protected void gvChild_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
GridViewRow gvMasterRow = (GridViewRow)e.Row.Parent.Parent.Parent.Parent;
}
}

<asp:GridView ID="gvParent" DataKeyNames="ID" runat="server" PageSize="1" AllowPaging="true"
PagerSettings-Mode="NextPrevious" AutoGenerateColumns="False" SkinID="GVCenter"
OnRowDataBound="gvParent_RowDataBound">
<Columns>
<asp:BoundField DataField="Name" />
<asp:TemplateField>
<ItemTemplate>
<asp:GridView ID="gvChild" DataKeyNames="ID" runat="server" AutoGenerateColumns="false"
ShowHeader="false" OnRowDataBound="gvChild_RowDataBound">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<%# (((IDataItemContainer)Container.Parent.Parent.Parent).DataItem as MyClass).MyProperty %>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ItemTemplate>
</asp:TemplateField>
</Columns>

Related

How do I disable LinkButton in gridview based on a value from another column?

I have a status column which includes approved, rejected or cancelled. I have another Actions column which contain link buttons approve and reject. Now if the status is Cancelled, I want the link button to be disabled for that row.
I tried to use GridView1_DataBound event but couldn't figure out the logic.
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if (Server.HtmlDecode(e.Row.Cells[0].Text.Trim()).Equals("Cancelled"))
{
//OR you can disable it instead of complately hiding it
((LinkButton)GridView1.Rows[e.Row.RowIndex].Cells[0].Controls[0]).Enabled = false;
}
}
}
Method A
The following should work:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:BoundField HeaderText="Status" DataField="Status" />
<asp:TemplateField HeaderText="Actions">
<ItemTemplate>
<asp:LinkButton runat="server" Enabled='<%# !(Eval("Status").ToString().Equals("Cancelled")) %>'>Approve</asp:LinkButton>
<asp:LinkButton runat="server" Enabled='<%# !(Eval("Status").ToString().Equals("Cancelled")) %>'>Reject</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Method B
Nevertheless, if you do insist on the code-behind approach the safest way to access the LinkButton controls is the following:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" OnRowDataBound="GridView1_RowDataBound">
<Columns>
<asp:BoundField HeaderText="Status" DataField="Status" />
<asp:TemplateField HeaderText="Actions">
<ItemTemplate>
<asp:LinkButton ID="ApproveButton" runat="server">Approve</asp:LinkButton>
<asp:LinkButton ID="RejectButton" runat="server">Reject</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if (e.Row.Cells[0].Text.Equals("Cancelled"))
{
((LinkButton)e.Row.FindControl("ApproveButton")).Enabled = false;
((LinkButton)e.Row.FindControl("RejectButton")).Enabled = false;
}
}
}
Explanation
Your code doesn't work because the LinkButton controls are not placed in the cell's Controls collection in the way you're expecting them to. Find out yourself by placing a breakpoint inside the inner condition of GridView1_RowDataBound and check out the items of the Controls collection. You'd be surprised!
Maybe you can use this code
<asp:GridView ID="gridView" runat="server" AutoGenerateColumns="False" OnRowDataBound="gridView_RowDataBound">
<Columns>
<asp:BoundField HeaderText="Column1" DataField="Column1" />
<asp:BoundField HeaderText="Column2" DataField="Column2" />
<asp:TemplateField HeaderText="Status">
<ItemTemplate>
<asp:Label runat="server" ID="lblStatus" Text='<%#Bind("Status") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Actions">
<ItemTemplate>
<asp:LinkButton ID="lnkAction" runat="server">Approve</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
protected void gridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var status = (e.Row.FindControl("lblStatus") as Label).Text;
if (status == "Cancelled")
{
(e.Row.FindControl("lnkAction") as LinkButton).DisableControl("Disabled button.");
}
}
}
And to disable the button you can use an extension method
public static class Extensions
{
public static TControl DisableControl<TControl>(this TControl control, string desableMessage) where TControl : WebControl
{
control.Attributes.Add("disabled", "");
control.Attributes.Add("data-toggle", "tooltip");
control.Attributes.Add("title", disableMessage);
control.Enabled = false;
return control;
}
}

I would like to ask about double clicked the data Gridview row then the code below layout

HTML CODE, this concept can work , but i need to apply it on my gridview table after data binded.
$(document).ready(function () {
$('.clickme').click(function() {
alert("Hello World");
});
});
<tr class="clickme">
<td>Shop: </td>
</tr>
<asp:GridView ID="dgMain" runat="server" AllowPaging="True" AllowSorting="True" AutoGenerateColumns="False" DataKeyNames="ChassisNo" OnPageIndexChanging="dgMain_PageIndexChanging"
OnRowCreated = "OnRowCreated" CssClass="table table-bordered" CellPadding="6" HeaderStyle-BackColor="#eeeeee" OnSorting="Sorting">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox id="chkSelection" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="No" >
<ItemTemplate>
<asp:Label id="LabelNo" runat="server" >
<%# GetIndex( DataBinder.Eval(Container, "RowIndex")) %>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="OperationName" HeaderText="Operation Name" SortExpression="OperationName"/>
<asp:BoundField DataField="OperationStart" HeaderText="Operation Start" SortExpression="OperationStart"/>
<asp:BoundField DataField="LOTNo" HeaderText="LOT No" SortExpression="LOTNo"/>
<asp:BoundField DataField="MSC" HeaderText="MSC" SortExpression="MSC" />
<asp:BoundField DataField="MaterialGroup" HeaderText="Material Group" SortExpression="MaterialGroup"/>
<asp:BoundField DataField="ChassisNo" HeaderText="Chassis No" SortExpression="ChassisNo" />
<asp:BoundField DataField="ColorID" HeaderText="Color ID" SortExpression="ColorID"/>
</Columns>
<PagerStyle HorizontalAlign="Center" />
<PagerSettings Mode="NumericFirstLast" />
</asp:GridView>
I would like to click on the row1 diagram below then will prompt out the message Hello world,
if i clicked on Row2 it will to display helloworld2.
__________________________________________________________________
|___Row1__________|_____Row1____|_______Row1_____|_____Row1________|
|___Row2__________|_____Row2____|_______Row2_____|_____Row2________|
|___Row3__________|_____Row3____|_______Row3_____|_____Row3________|
|___Row4__________|_____Row4____|_______Row4_____|_____Row4________|
If you wants to display just alert with rowNumber then it is so simple
Use
onrowdatabound="CustomersGridView_RowDataBound" for Your gridview
<asp:gridview id="CustomersGridView"
autogeneratecolumns="true"
allowpaging="true"
onrowdatabound="CustomersGridView_RowDataBound"
runat="server">
</asp:gridview>
and on Server Side
public void CustomersGridView_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes.Add("onclick", "alert('helloworld " + e.Row.RowIndex + "')");
}
}

Delete GridView Rows in button cick without RowDeleting that not saved in DB

I have a gridview,
When Button ADD is clicked the textboxs values will be added to gridview.
After adding values to gridview i want to select a row and click delete button but error occurs to me on deleting.
My GridView Code
<asp:GridView ClientIDMode="Static" ID="GridPesonal" runat="server" AutoGenerateColumns="False" Class="GrdSty" Width="100%" DataKeyNames="RowNumber">
<Columns>
<asp:BoundField DataField="RowNumber" HeaderText="ردیف">
</asp:BoundField>
<asp:BoundField DataField="StartDate" HeaderText="از تاریخ">
</asp:BoundField>
<asp:BoundField DataField="EndDate" HeaderText="تا تاریخ">
</asp:BoundField>
<asp:BoundField DataField="SherkatName" HeaderText="نام شرکت،سازمان یا موسسه" >
</asp:BoundField>
<asp:BoundField DataField="WorkUnitName" HeaderText="واحد محل کار">
</asp:BoundField>
<asp:BoundField DataField="Sharh" HeaderText="شرح دقیق شغل/سمت/مسئولیت" >
</asp:BoundField>
<asp:BoundField DataField="WorkTime" HeaderText="زمان کار" >
</asp:BoundField>
<asp:BoundField DataField="Description" HeaderText="توضیحات">
</asp:BoundField>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="SavabegSelect" runat="server" AutoPostBack="True" OnCheckedChanged="SavabegSelect_CheckedChanged" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<EmptyDataTemplate>
موردی ثبت نشده است.
</EmptyDataTemplate>
</asp:GridView>
Btn Delete Code
<asp:Button ClientIDMode="Static" ID="BtnDelete" CssClass="btnregister" runat="server" Text="حذف" OnClick="BtnDelete_Click" />
Code behind of btn Delete
protected void BtnDelete_Click(object sender, EventArgs e)
{
foreach (GridViewRow gvrow in GridPesonal.Rows)
{
CheckBox chkdelete = (CheckBox)gvrow.FindControl("SavabegSelect");
if (chkdelete.Checked)
{
GridPesonal.DeleteRow(gvrow.RowIndex);
}
}
}
When execute above code this error show
The GridView 'GridPesonal' fired event RowDeleting which wasn't handled.
Have you used command-name as Delete on BtnDelete.
Remove that from Delete Button it will work.
If you have like this
<asp:GridView ID="gvRoute" DataKeyNames="Route" runat="server" AutoGenerateColumns="false"
AllowPaging="true" Width="30%"
onrowdeleting="gvRoute_RowDeleting">
Remove onrowdeleting="gvRoute_RowDeleting
or wirte event for
protected void gvRoute_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
\\
}
or Use the "CommandName" property "Delete"
Or Use OnClick
<asp:GridView ClientIDMode="Static" ID="GridPesonal" runat="server" AutoGenerateColumns="False" Class="GrdSty" Width="100%" DataKeyNames="RowNumber" OnClick="BtnDelete">

image button click inside gridview is not fetching datakeynames

Here i need to get the DataKeyNames on which row i click(in side tools column image button click)
but when i click on the imagebutton(pencil) it show the following error
my C# codes is
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Edit")
{
ImageButton btnedit = sender as ImageButton;
GridViewRow gvrow = btnedit.NamingContainer as GridViewRow;
int sid = Convert.ToInt32(GridView1.DataKeys[gvrow.RowIndex].Value);
Response.Write(sid);
}
else if (e.CommandName == "Delete")
{
}
}
my Gridview source codes
<asp:GridView ID="GridView1" runat="server" OnRowCommand="GridView1_RowCommand" AutoGenerateColumns="False" OnSelectedIndexChanged="GridView1_SelectedIndexChanged" DataKeyNames="StdId" BackColor="White" BorderColor="White" BorderStyle="Ridge" BorderWidth="2px" CellPadding="3" CellSpacing="1" EnableModelValidation="True" GridLines="None">
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" />
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="CheckBox2" runat="server"></asp:CheckBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Name">
<ItemTemplate><%#Eval("Name") %></ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Email">
<ItemTemplate><%#Eval("Email") %></ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Mobile">
<ItemTemplate><%#Eval("Mobile") %></ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="City">
<ItemTemplate><%#Eval("City") %></ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Tools">
<ItemTemplate>
<asp:ImageButton ID="imgbtnEdit" runat="server" CommandArgument="ImageButton" CommandName="Edit" ImageUrl="~/pencil.png" ToolTip="Click To Edit" AlternateText="Click To Edit"/>
<asp:ImageButton ID="imgbtnDelete" runat="server" CommandName="Delete" ImageUrl="~/cross.png" ToolTip="Click To Dletee" AlternateText="Click To Dletee"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<FooterStyle BackColor="#C6C3C6" ForeColor="Black" />
<HeaderStyle BackColor="#4A3C8C" Font-Bold="True" ForeColor="#E7E7FF" />
<PagerStyle BackColor="#C6C3C6" ForeColor="Black" HorizontalAlign="Right" />
<RowStyle BackColor="#DEDFDE" ForeColor="Black" />
<SelectedRowStyle BackColor="#9471DE" Font-Bold="True" ForeColor="White" />
</asp:GridView>
please help me how to get the DatakeyName
First you need to add an OnRowCreated event to your gridview
OnRowCreated="GridView1_RowCreated"
An in .cs file add this ( set the Rowindex value in CommandArgument so you can get this on RoeCommand)
protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
ImageButton imgbtnEdit= (ImageButton)e.Row.FindControl("lnkUrlID");
imgbtnEdit.CommandArgument = e.Row.RowIndex.ToString();
ImageButton imgbtnDelete= (ImageButton )e.Row.FindControl("lnkExtend");
imgbtnDelete.CommandArgument = e.Row.RowIndex.ToString();
}
}
Now at your GridView1_RowCommand try this
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Edit")
{
int sid = Convert.ToInt32(GridView1.DataKeys[Convert.ToInt32(e.CommandArgument)].Value);
}
}

Get id from gridview

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="Id" DataSourceID="EmptyL" AllowPaging="True"
AllowSorting="True" GridLines="Vertical"
OnRowUpdating="TaskGridView_RowUpdating">
<Columns>
<asp:BoundField DataField="Id" HeaderText="Id" InsertVisible="False" ReadOnly="True" SortExpression="Id" />
<asp:CommandField ShowEditButton="True" />
<asp:CheckBoxField DataField="Status" HeaderText="Status" SortExpression="Status"/>
</Columns>
</asp:GridView>
<asp:LinqDataSource ID="EmptyLeg" runat="server"
ContextTypeName="Dev.Orpheus.App_Data.DataStorageDataContext"
EnableDelete="True" EnableInsert="True" EnableUpdate="True"
EntityTypeName="" OrderBy="Id desc" TableName="EmptyL">
</asp:LinqDataSource>
protected void TaskGridView_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
Label1.Text = ?????? updated ID ???????
}
Classical gridview data from linq
For example I update the field "Status"
How to get the ID of the updated object ?
You should get it in NewValues collection of GridViewUpdateEventArgs parameter
like this
e.NewValues["Id"]
for that you can use
<%# DataBinder.Eval(Container.DataItem, "Id") %>
method on CheckBoxField so that in
protected void TaskGridView_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
Label1.Text = //Chechbox value
}
and can update database or other filed as per necessary
Have a Good day.
Label1.Text = e.Keys[0]
The grid contains a primary .Keys property.

Categories

Resources