Findcontrol failed for templatefield (linkbutton) in detailsView - asp.net

I would like to set a templatefield (linkbutton) to invisible when the DetailsView is not in ReadOnly mode. I created a linkbutton to replace the auto-gen "delete" button and want to hide it when editing and inserting.
<asp:DetailsView ID="resultDetailsView" runat="server" AutoGenerateRows="False" DataKeyNames="smo_code,id"
DataSourceID="detailviewDataSource" Height="50px" Width="125px" OnItemInserting="resultDetailsView_ItemInserting"
OnItemUpdating="resultDetailsView_ItemUpdating" OnItemUpdated="resultDetailsView_ItemUpdated"
OnItemDeleted="resultDetailsView_ItemDeleted" OnItemInserted="resultDetailsView_ItemInserted"
OnItemDeleting="resultDetailsView_ItemDeleting" OnModeChanging="resultDetailsView_ModeChanging"
OnDataBound="resultDetailsView_DataBound" OnItemCommand="resultDetailsView_ItemCommand">
<Fields>
<asp:BoundField DataField="event" HeaderText="event" SortExpression="event" />
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:LinkButton ID="deleteLink" runat="server" CommandName="Delete" Text="Delete"
OnClientClick='return confirm("Are you sure you want to delete this item?");' />
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowDeleteButton="False" ShowEditButton="True" ShowInsertButton="True" />
</Fields>
</asp:DetailsView>
IN CODE BEHIND, FINDCONTROL returned null:
protected void resultDetailsView_DataBound(object sender, EventArgs e)
{
LinkButton deleteLink = (LinkButton)resultDetailsView.FindControl("deleteLink");
if (resultDetailsView.CurrentMode == DetailsViewMode.ReadOnly)
{
deleteLink.Visible = true;
}
else
{
deleteLink.Visible = false;
}
}

You can do it after .DataBind() method. Here is a good example
How to dynamically hide fields in a DetailsView (fields count is always 0)
Or even this too is a good example
Listview/DetailsView: Hide a null field

Related

Model binding to formview when Gridview Edit button is clicked

I have searched here and on google as well.Things are not working so I'm posting this.
I have two controls GridView and FormView.I am using Model binding in my project.
<asp:GridView ID="GridView1" runat="server" DataKeyNames="Id" ItemType="Sample.Shared.ViewModel.ProfileMasterView"
AutoGenerateColumns="false" SelectMethod="Select_GridView">
<Columns>
<asp:BoundField DataField="Name" HeaderText="Name" />
<asp:BoundField DataField="Designation" HeaderText="Designation" />
<asp:BoundField DataField="EmailAddress" HeaderText="EmailAddress" />
<asp:TemplateField HeaderText="Action">
<ItemTemplate>
<asp:Button ID="Edit_Profile" OnClick="btnEdit_OnClick" runat="server" Text="Edit" CommandArgument="<%# BindItem.Id %>" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:FormView ID="fvProfile" runat="server" RenderOuterTable="False" ItemType="Sample.Shared.ViewModel.ProfileMasterView"
DefaultMode="Insert" InsertMethod="Insert_Profile" >
I want to open FormView in Edit mode , where in gridview i am sending id of that record.On button click i want to change formview mode by calling BLL method which takes that Id from button click and retrieved record displayed in form view in edit mode.
Please help me , how can i implement this or any other similar way using model binding only,
Thank you.
As no one seems to answer this.I have found work around and also proper method for doing,I will add the answer as i get time from work.
before
asp:Button ID="Edit_Profile" OnClick="btnEdit_OnClick" runat="server" Text="Edit" CommandArgument="<%# BindItem.Id %>"
asp:FormView ID="fvProfile" runat="server" RenderOuterTable="False" ItemType="Sample.Shared.ViewModel.ProfileMasterView"
DefaultMode="Insert" InsertMethod="Insert_Profile"
after
asp:Button ID="Edit_Profile" OnCommand="btnEdit_OnClick" runat="server" Text="Edit" CommandArgument="<%# BindItem.Id %>"
asp:FormView ID="fvProfile" runat="server" RenderOuterTable="False" ItemType="Sample.Shared.ViewModel.ProfileMasterView" SelectMethod="Get"
DefaultMode="Insert" InsertMethod="Insert_Profile"
protected void btnEdit_OnClick(object sender, CommandEventArgs e)
{
gId = Convert.ToInt32(e.CommandArgument.ToString());
fvProfile.ChangeMode(FormViewMode.Edit);
fvProfile.Visible = true;
GridView1.Visible = false;
fvProfile.DataBind();
}
public DAL2.Models.OfficialDocument Get()
{
if(gId == 0)
{
ChangeViewMode();
return null;
}
BLL.ManageOfficialDocument mod = new BLL.ManageOfficialDocument();
var od = mod.GetById(gFILES_ID);
return od;
}
private int gId;

Cannot find control in EditTemplate via OnRowEditing event

I have a GridView like so:
<asp:GridView runat="server" ID="grdPractices" PageSize="10" AutoGenerateColumns="False" DataKeyNames="Id"
CssClass="linkGrid" AllowSorting="True" OnSorting="grdPractices_OnSorting" OnRowDataBound="grdPractices_OnRowDataBound"
OnRowEditing="grdPractices_OnRowEditing" OnRowCancelingEdit="grdPractices_OnRowCancelingEdit" OnRowUpdating="grdPractices_OnRowUpdating">
<Columns>
<asp:BoundField DataField="Name" HeaderText="Name" meta:resourcekey="PracticeName" ReadOnly="True" SortExpression="Name" ItemStyle-Width="400px" />
<asp:BoundField DataField="Code" HeaderText="Code" meta:resourcekey="Code" ReadOnly="True" SortExpression="Code" ItemStyle-Width="200px" />
<asp:TemplateField meta:resourcekey="SiteName" ItemStyle-Width="200px" SortExpression="SiteName">
<ItemTemplate>
<asp:Literal runat="server" Text='<%# Eval("SiteName") %>' />
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList runat="server" ID="lstSites" />
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField meta:resourcekey="NumOfUsers" ItemStyle-Width="200px" SortExpression="NumOfUsers">
<ItemTemplate>
<asp:LinkButton runat="server" OnCommand="OnLinkButtonCommand" CommandName="ViewUsers" Text='<%# Eval("NumOfUsers") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowDeleteButton="False" ShowCancelButton="True"
ShowInsertButton="False" ShowEditButton="True" EditText="Edit"
CancelText="Cancel" UpdateText="Update" meta:resourcekey="Edit" ItemStyle-Width="200px" />
</Columns>
</asp:GridView>
and here is the code for the OnRowEditing event:
protected void grdPractices_OnRowEditing(object sender, GridViewEditEventArgs e)
{
this.grdPractices.EditIndex = e.NewEditIndex;
var sitesDropDown = this.grdPractices.Rows[e.NewEditIndex].Controls[0].FindControl("lstSites") as DropDownList;
if (sitesDropDown == null)
{
return;
}
}
My problem is that I cannot get a hold of the lstSites control, which lives in the EditTemplate. I've tried using the following:
this.grdPractices.Rows[e.NewEditIndex].Controls[0].FindControl("lstSites")
as DropDownList;
this.grdPractices.Rows[e.NewEditIndex].FindControl("lstSites") as
DropDownList;
this.grdPractices.Rows[e.NewEditIndex].FindControlRecursive("lstSites")
as DropDownList;
The result is always the same, a NULL is returned.
How on earth are you supposed to get a control in a row when in the OnRowEditing event?
OK, what I was not doing, after this line:
this.grdPractices.EditIndex = e.NewEditIndex;
was then rebinding the grid's data. So after rebinding the data, and then calling:
var sitesDropDown = this.grdPractices.Rows[e.NewEditIndex].FindControlRecursive("lstSites") as DropDownList;
I am now able to interact with the siteDropDown variable since it now contains a reference to the lstSites control.
Try to use GridViewRow as following...
protected void grd_RowEditing(object sender, GridViewEditEventArgs e)
{
GridViewRow selectRow = grd.Rows(e.NewEditIndex);
DropDownList sitesDropDown =(DropDownList)selectRow.Cells[2].FindControl("lstSites");
}

Edit button text in GridView

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")
{
}
}

ASP.NET Grid View Problem

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" .... >

GridView: Retrieve value of TemplateField in RowDeleting event

My gridview is bound to List when users click a refresh button as follows:
grv_xyz.DataSource = lstVendorInfo;
grv_zyz.DataBind();
I put a <asp:CommandField HeaderText="Delete" ShowDeleteButton="True" ShowHeader="True" /> before all other TemplateFields to display data like
<Columns>
<asp:CommandField HeaderText="Delete" ShowDeleteButton="True" ShowHeader="True" />
<asp:TemplateField HeaderText="Vendor ID">
<ItemStyle Width="10%" BorderColor="#efefef" BorderWidth="1px"/>
<ItemTemplate>
<asp:HyperLink NavigateUrl="#" ID="abcID" runat="server" Text='<%# Bind("abc") %>'></asp:HyperLink>
</ItemTemplate>
<HeaderStyle BorderColor="#efefef" />
</asp:TemplateField>
</Columns>
The problem is cell. Text property in the following is "".
protected void grv_Vendor_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
ShowResult();
TableCell cell = grv_Vendor.Rows[e.RowIndex].Cells[4];
}
How could I retieve the value inside a TemplateField in RowDeleting event?
Thanks a lot.
A TemplateField includes controls, so the value should be accessed through them. For example, if you have a label inside a TemplateField and you want to access its value, you would write:
Label yourLabel = e.Item.FindControl("YourLabelID") as Label;
string val = yourLabel.Text;

Resources