GridView DataBind does not work - asp.net

I am using ASP.NET Membership and Linq. I have a problem here: I show all users inside a grid view that has a delete button. Take a look at this code:
<asp:GridView
ID="UsersGridView"
runat="server"
AutoGenerateColumns="False"
DataSourceID="UsersLinqDataSource"
AllowPaging="True">
<Columns>
<asp:BoundField DataField="UserName" HeaderText="UserName" ReadOnly="True" SortExpression="UserName" />
<asp:BoundField DataField="LastActivityDate" HeaderText="LastActivityDate" ReadOnly="True" SortExpression="LastActivityDate" />
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="DeleteButton" runat="server" CommandArgument='<%# Eval("UserName") %>' Text="Delete" OnClick="DeleteButton_Click"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:LinqDataSource
ID="UsersLinqDataSource"
runat="server"
ContextTypeName="TraceWeb.DataModel.DataContextDataContext"
EntityTypeName=""
Select="new (UserName, LastActivityDate)"
TableName="Users"
EnableDelete="True">
</asp:LinqDataSource>
And Delete button's event handler:
protected void DeleteButton_Click(object sender, EventArgs e)
{
String username = (String)((sender as IButtonControl).CommandArgument);
Membership.DeleteUser(username, true);
UsersGridView.DataBind();
}
But problem is that after running this code and deleting a user, GridView still shows that user.

This happens because Membership and UsersLinqDataSource are not connected and if you "refresh" the UsersLinqDataSource status and then rebind your grid, all will be displayed properly.
protected void DeleteButton_Click(object sender, EventArgs e)
{
String username = (String)((sender as IButtonControl).CommandArgument);
Membership.DeleteUser(username, true);
// first solution: may not work properly
UsersLinqDataSource = yourLinqData;
// second solution: work
UsersLinqDataSource = null;
UsersLinqDataSource = yourLinqData;
UsersGridView.DataBind();
}

Related

issue in using dynamic grid link button for scriptManager.RegisterPostBackControl (control) as this has to be declared at page_load

I was trying to download csv file on grid's dynamically created link button.
I was facing issue while downloading csv in asp.net.
Exception : Sys.WebForms.PageRequestManagerParserErrorException
This Exception is resolved by using code:
ScriptManager scriptManager = ScriptManager.GetCurrent(this.Page);
scriptManager.RegisterPostBackControl(this.grouplnkbutton);
at page_load event,but this.grouplnkbutton (dynamically created link button i.e. grouplnkbutton control is not available at page_load event).
how can i use linkbutton with scriptmanager at page_load event.
Code:
protected void Page_Load(object sender, EventArgs e)
{
ScriptManager scriptManager = ScriptManager.GetCurrent(this.Page);
scriptManager.RegisterPostBackControl(this.grouplnkbutton);
//codes
}
protected void hlGroupName_Click(object sender, EventArgs e)
{
try`enter code here`
{
Response.ClearHeaders();
Response.ClearContent();
grouplnkbutton = sender as LinkButton;
string linkBtnValue = grouplnkbutton.CommandArgument;
GridDataItem item = grouplnkbutton.NamingContainer as GridDataItem;
ExportToCSV exportToCSV = new ExportToCSV();
StringBuilder csv = new StringBuilder();
DataSet gridData = new DataSet();
int scheduleId = Convert.ToInt32(((HiddenField)item.FindControl("hidID")).Value);
csv = exportToCSV.ExportScheduleDataToCSV(scheduleId);
Response.Buffer = true;
Response.Clear();
Response.ContentType = "text/csv";
Response.AddHeader("content-disposition", "attachment;filename=perfscheduleReport.csv");
//Response.Charset = "";
Response.Output.Write(csv.ToString());
//Response.Write(csv.ToString());
Response.Flush();
//Response.End();
}
Thanks for solution.
markup code
<telerik:RadGrid ID="PerfGrid" GridLines="None" runat="server" CssClass="BorderGrid" OnItemDataBound="PerfGrid_ItemDataBound" OnItemCommand ="PerfGrid_ItemCommand"
Skin="Default" Width="100%" PageSize="100" PagerStyle-PageSizeLabelText="Records Per Page" AllowFilteringByColumn="true" OnNeedDataSource="PerfGrid_NeedDataSource" OnPageIndexChanged="PerfGrid_PageIndexChanged">
<ClientSettings EnableRowHoverStyle="true">
<Resizing AllowColumnResize="True" AllowRowResize="false" ResizeGridOnColumnResize="false"
ClipCellContentOnResize="true" EnableRealTimeResize="false" AllowResizeToFit="true" />
</ClientSettings>
<MasterTableView CommandItemDisplay="None" HorizontalAlign="NotSet" AllowPaging="false" AutoGenerateColumns="False" AllowSorting="true" AllowFilteringByColumn="True">
<HeaderStyle CssClass="GridHeader" Font-Bold="true"></HeaderStyle>
<ItemStyle BackColor="White" CssClass="text2" HorizontalAlign="Left" />
<AlternatingItemStyle BackColor="#E6EEF8" CssClass="text2" HorizontalAlign="Left" />
<%--<PagerStyle AlwaysVisible="true" Mode="NextPrevAndNumeric" />--%>
<Columns>
<telerik:GridBoundColumn DataField="ScheduleId" Display="false" ReadOnly="true" HeaderText="ID" AllowFiltering="false" HeaderStyle-Width="10px">
</telerik:GridBoundColumn>
<telerik:GridTemplateColumn HeaderText="Select" HeaderStyle-Width="15px" AllowFiltering="false">
<ItemTemplate>
<asp:CheckBox ID="CheckSelect" runat="server"></asp:CheckBox>
</ItemTemplate>
</telerik:GridTemplateColumn>
<telerik:GridTemplateColumn DataField="GroupingName" ReadOnly="true" HeaderText="Group Name" SortExpression="GroupName" HeaderStyle-Width="20px">
<ItemTemplate>
<asp:LinkButton ID="hlGroupName" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "GroupingName") %>' OnClick="hlGroupName_Click"></asp:LinkButton> <%--CommandName="Export"--%>
<%--<asp:HyperLink ID="hlTestCase" CommandName="Edit1" runat="server" Text='<%# Container.DataItem("TestDescription") %>'--%>
Target="_self"></asp:HyperLink>--%>
<asp:HiddenField ID="hidID" runat="server" Value='<%# CheckNull(DataBinder.Eval(Container.DataItem, "ScheduleId") , false)%>' />
<%--Value='<%# Container.DataItem("Id") %>' Value='<%# DataBinder.Eval(Container.DataItem, "Id") %>--%>
</ItemTemplate>
</telerik:GridTemplateColumn>
<telerik:GridBoundColumn SortExpression="TestDescription" DataField="TestDescription" ReadOnly="true" HeaderText="Test Cases" HeaderStyle-Width="30px">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn SortExpression="ServerIP" DataField="ServerIP" ReadOnly="true" HeaderText="Server IP" HeaderStyle-Width="20px">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn SortExpression="LoadNoOfUsersTobeSimulated" DataField="LoadNoOfUsersTobeSimulated" HeaderText="Users Load" ReadOnly="true" HeaderStyle-Width="12px">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn SortExpression="StartTime" DataField="StartTime" HeaderText="Start Time" ReadOnly="true" HeaderStyle-Width="25px">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn SortExpression="EndTime" DataField="EndTime" HeaderText="End Time" ReadOnly="true" HeaderStyle-Width="25px">
</telerik:GridBoundColumn>
</Columns>
</MasterTableView>
</telerik:RadGrid>
in this lnkbtn - ID -"hlGroupname" onclick event i want to downalod csv
But getting Exception:Sys.WebForms.PageRequestManagerParserErrorException
resolved Exception using :
protected void Page_Load(object sender, EventArgs e)
{
ScriptManager scriptManager = ScriptManager.GetCurrent(this.Page);
ScriptManager.RegisterPostBackControl(this.PerfGrid);
//codes
}
I am using Scriptmanager as my grid is under updatepanel.
Here PerfGrid is telerikGrid control. Instead of grid control i want to use dynamically created grid link button. And onclick event of lnkbutton i want to download csv.
Hum, your code looks fine, but why the need for the register script?
dump that code you have in the load event, I don't see a need for it??
You not posted your markup, but say a grid like this:
<asp:GridView ID="GridView1" runat="server" CssClass="table" AutoGenerateColumns="False" DataKeyNames="ID">
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False" ReadOnly="True" />
<asp:BoundField DataField="ProjectName" HeaderText="ProjectName" />
<asp:BoundField DataField="ProjectDate" HeaderText="ProjectDate" />
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton runat="server" OnClick="LinkButton1_Click">My Link</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Your button code then as you have looks fine.
I don't (so far) on what you posted see why any need for register script or that button event needs that code. You can just wire up the click event as you have, nothing more need be done.
So, in above, the linkbutton should be just fine. Check and REMOVE the post-back URL setting for that link button - that might be your issue (but, you not posted at least the markup you have for the LinkButton.
It should only require the click even code you have - no other settings such as post-back URL is required for that button click event to work. In fact, it not at all clear why you using a LinkButton as opposed to say a button? (I see no need for a link button ).
So, no real reason for the register script stuff - remove it.
And note how I don't have to include the PK row "ID" in the markup, or even a hidden field. The datakeys setting is just for that reason (and it nice from a secuirty point of view - I don't have to render the PK row ID has hiddefield or anything.
Hence this code can get the PK id
protected void LinkButton1_Click(object sender, EventArgs e)
{
LinkButton lBtn = sender as LinkButton;
GridViewRow gRow = lBtn.NamingContainer as GridViewRow;
// get row click index with gRow.RowIndex
int? pkID = GridView1.DataKeys[gRow.RowIndex]["ID"] as int?;
And my code to fill the gv was this:
using (SqlCommand cmdSQL = new SqlCommand("SELECT * from Project"L, conn))
{
conn.Open();
GridView1.DataSource = cmdSQL.ExecuteReader();
GridView1.DataBind();
}
Now, of course if you using the row data bound for ANY thing at all? Then don't bind the GV to the reader, but use this:
conn.Open();
DataTable rstData = new DataTable();
rstData.Load(cmdSQL.ExecuteReader();
GridView1.DataSource = rstData;
GridView1.DataBind();

Asp.net GridView - Getting row identifier

I have a page that displays orders in GridView and each row has a details- and delete-button. Most of the time everything works fine, but if new order arrives between the page refresh and button clicking, wrong order is processed.
I save unique identifier to CommandArgument, but it seems that the identifier in question isn't passed back to server, but instead some kind of counter (e.g. 5th order) and since after the arrival of new order the right one would be 6th, everything goes wrong... What's up with that?
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" PageSize="20"
EnableViewState="False" EnableSortingAndPagingCallbacks="True"
DataSourceID="ldsOrders" AllowPaging="True"
ondatabound="gvOrders_DataBound" CssClass="Gridview" >
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False"
ReadOnly="True" SortExpression="ID" />
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btnDelete" runat="server" CommandArgument='<%#Eval("ID") %>' CommandName="Delete"
Text="Delete" OnClick="btnDelete_Click" CausesValidation="False" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btnOrder" runat="server" CommandArgument='<%#Eval("ID") %>' CommandName="Order"
Text="Order" OnCommand="btnOrder_Click" CausesValidation="False" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code-Behind:
protected void btnDelete_Click(object sender, CommandEventArgs e)
{
string orderID = (string)e.CommandArgument;
da.DeleteOrder(Convert.ToInt32(orderID));
Response.Redirect(Request.RawUrl, false);
}
Without any code examples here is something to try...
Assuming that ID is the primary key - you should set that in the GridView DataKeys property. You should not place primary keys in a viewable area.
Where you specify the CommandArgument: that should be the rowindex that is set in the RowDataBound event such that:
//(note this is pseudo-code, but you should get the basic idea)
if( e.row.rowtype == datarow )
{
Button btn = (Button) e.row.findcontrol("btnDelete") ;
btn.CommandArgument = e.row.rowIndex ;
}
And in the delete click event obtain the primary key from the gridview datakeys:
protected void btnDelete_Click(object sender, CommandEventArgs e)
{
int orderIDIdx = (Convert.ToInt32(e.CommandArgument);
int pkey = Convert.ToInt32(Gridview1.Datakeys(orderIDidx).value
da.DeleteOrder(pkey);
Response.Redirect(Request.RawUrl, false);
}
Obviously, add appropriate error checking where applicable.
You should set the DataKeyNames
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.datakeynames.aspx
<asp:GridView ID="Gridview1" DataKeyNames="ID" .... >
then the command delete trigger the RowDeleting event
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.rowdeleting.aspx
which can be used to delete the row using e.Keys[0] to retrieve the id
protected void Gridview1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
Int orderID = Convert.ToInt32(e.Keys[0].ToString());
da.DeleteOrder(Convert.ToInt32(orderID));
}

Findcontrol failed for templatefield (linkbutton) in detailsView

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

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

Editable Gridview with code behind data source from ODBC

I am trying to make a small gridview that lists the results of a query against a non standard SQL db, and with this information I want the user to be able to edit a column or two to update the data in the db. I know this is easy with an sqldatasource control but I lack that luxury and I am having trouble switching from my itemTemplates in the gridview to the edittemplates when I fire the gridview's edit event.
any pointers?
some code:
<asp:GridView ID="ExamEditGridView" runat="server" OnRowEditing="EditExam" OnRowUpdating="SaveEdit"
DataKeyNames="iproc_code" AllowSorting="true" AutoGenerateColumns="false" AutoGenerateEditButton="true">
<HeaderStyle BackColor="#006633" Font-Bold="True" ForeColor="White" />
<EditRowStyle BackColor="#999999" />
<Columns>
<asp:TemplateField HeaderText="Exam Title">
<ItemTemplate>
<asp:Label ID="col1" runat="server" Text='<%# Bind("rpt_descrip") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="EditText" runat="server" Text='<%# Bind("rpt_descrip") %>' Visible="false" />
</EditItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="Short Description" DataField="short_descrip" />
<asp:BoundField HeaderText="Description" DataField="descrip" />
<asp:BoundField HeaderText="Sched Note" DataField="sched_note" />
</Columns>
</asp:GridView>
code behind:
(the query is just a simlpe select statement)
string mod_id = modSelect.SelectedValue;
string query = qry + mod_id;
using (OdbcConnection connection = new OdbcConnection(DbConnectionString))
{
OdbcDataAdapter adapter = new OdbcDataAdapter(query, connection);
DataTable dt = new DataTable();
connection.Open();
adapter.Fill(dt);
ExamEditGridView.DataSource = dt;
ExamEditGridView.DataBind();
}
the gridview is databound when a dropdown lists index changes, which gives me the mod_id for the query
I ended up getting it working, I didn't realize I had to set the gridview's editindex value and redatabind to toggle edit mode
code:
protected void EditExam(object sender, GridViewEditEventArgs e)
{
ExamEditGridView.EditIndex = e.NewEditIndex;
ExamEditGridView.DataSource = Session["data"];
ExamEditGridView.DataBind();
}
protected void CancelEdit(object sender, GridViewCancelEditEventArgs e)
{
ExamEditGridView.EditIndex = -1;
ExamEditGridView.DataSource = Session["data"];
ExamEditGridView.DataBind();
}

Resources