I am having trouble with my datatable, at the moment my datatable is populated with values from my database. When i upload a new file into the database, my datatable would automatically update and show what it has been updated with. But now i have a button which deletes a record from the database which is in correlation with the datatable that i have. The problem right now is that after i have deleted the record, the datatable is not refreshing and it still shows the record there. I have verified that the record has been deleted, its just that my datatable wont update.(It will only update after i refreshed the page). Below are my codes for the datatable, and delete button
Data Table:
<asp:GridView ID="FileTableView" CssClass="datagrid" HeaderStyle-CssClass="datagridHeader" RowStyle-CssClass="datagridRows" runat="server" AutoGenerateColumns="False" DataKeyNames="fileid, filename">
<Columns>
<asp:TemplateField HeaderText="Master Folder">
<ItemTemplate>
<asp:LinkButton ID="FileLinkButton" CommandName="ShowPopup" OnCommand="File_Command" CommandArgument='<%# Eval("fileid") %>' runat="server" Text='<%# Eval("filename") %>'></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Filling data into the datatable
DataTable dtFile;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// Fill up file and folder data on the display
FillDataFile();
}
}
private void FillDataFile()
{
dtFile = new DataTable();
SqlDataReader reader = MBFile.GetFileToDisplay(Context.User.Identity.Name);
dtFile.Load(reader);
if (dtFile.Rows.Count > 0)
{
FileTableView.DataSource = dtFile;
FileTableView.DataBind();
}
}
Delete button
protected void File_Command(object sender, CommandEventArgs e)
{
string command = e.CommandName;
MBFile file;
switch (command)
{
case "ShowPopup":
System.Diagnostics.Debug.WriteLine("Running");
long fileid = Convert.ToInt64(e.CommandArgument.ToString());
System.Diagnostics.Debug.WriteLine("FileID: " + fileid);
file = MBFile.RetrieveFile(Context.User.Identity.Name, fileid);
LblFileID.Text = fileid.ToString();
LblFileName.Text = file.fileName;
LblFileType.Text = file.fileType;
LblFileSize.Text = file.fileSize.ToString();
ScriptManager.RegisterStartupScript(this, this.GetType(), "myModal", "showPopup();", true);
break;
case "Delete":
System.Diagnostics.Debug.WriteLine("Deleting");
MBFile.DeleteFile(Context.User.Identity.Name, Convert.ToInt64(LblFileID.Text));
FillDataFile();
break;
case "Download":
System.Diagnostics.Debug.WriteLine("Downloading");
DownloadFileContent(Context.User.Identity.Name, Convert.ToInt64(LblFileID.Text));
Page.ClientScript.RegisterStartupScript(Page.GetType(), "Delete Status", "<script language='javascript'>alert('" + "File has been deleted" + "')</script>");
break;
}
}
Inside FillDataFile there is this condition
if (dtFile.Rows.Count > 0)
{
FileTableView.DataSource = dtFile;
FileTableView.DataBind();
}
If you have deleted the only one record present in the table then this condition prevents the rebind of your grid. In any case this condition is wrong per se. If you don't have records in the table you should bind the result anyway. Remove the if condition.
I am not properly getting about your question so below is my answer
If you want your grid view data update after delete then just add this line just after delete
YourGridView.DataSource = YourDataTable;
YourGridView.DataBind();
If you want your datatable to be update after delete then just add this line
YourDataTable.AcceptChanges();
Related
I want to pass or store in Session Item clicked in GridView from one Page to another and passing the same parameter to my Stored Procedure to get data for the particular field.
I have created a grid view where data is coming from Store Procedure.
One of the GridView fields is LinkButton. So on click of link button it should show all the details of the applicant in a new tab. The page is getting redirected but I am not able to store or pass particular field which is "APPL_REF_NO" as mention in code.
ASP Code
<asp:GridView ID="gvServiceApplication" runat="server" AutoGenerateColumns="false" EmptyDataText="No Data Found"
Width="100%" HeaderStyle-BackColor="#facf5a"
HeaderStyle-ForeColor="Black" RowStyle-BackColor="White"
RowStyle-ForeColor="Black">
<Columns>
<asp:TemplateField HeaderText="ApplicationNo">
<ItemTemplate>
<asp:LinkButton ID="lblApplicationNo" runat="server" Text='<%#Eval("APPL_REF_NO") %>' OnClick="btnApplicantDetails_Click"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
protected void btnApplicantDetails_Click(object sender, EventArgs e)
{
Page.ClientScript.RegisterStartupScript(
this.GetType(), "OpenWindow", "window.open
('ApplicantDetails.aspx','_blank');", true);
}
private void ApplicationDetailBind()
{
try
{
DataTable dtApplicationDetail = new DataTable();
dtApplicationDetail = objDepartmentWiseBA.getApplicantDetails(applicationnumber).Tables[0];
gvApplicationIndetail.DataSource = dtApplicationDetail;
gvApplicationIndetail.DataBind();
}
catch (Exception)
{
throw;
}
}
We need to show application details based on parameter passed from LinkButton.
This paramters passed will again be used in StoredProcedure to bind another grid in ApplicantDetails Page. Thanks
Use the following line in place of second line in link button click event.
The approach is to pass the desired value as a query string parameter to ApplicationDetails.aspx page. A query string parameter can then be easily obtained using the second code snippet.
Second line in link button click event
this.GetType(), "OpenWindow",
String.Format("window.open('ApplicantDetails.aspx?applRefNo={0}','_blank');", (sender as LinkButton).Text ), true);
Then in your destination page you can use following C# code to get the value of APPL_REF_NO.
Get the value in destination page
var applRefNoValue = Request.QueryString["applRefNo"];
Instead of storing the value in a session variable, I'd suggest to transmit the value as Request parameter to the page that is opened. So you'd have to extend the URL that is called with the refNo of the row:
protected void btnApplicantDetails_Click(object sender, EventArgs e)
{
var refNo = ((LinkButton)sender).Text;
Page.ClientScript.RegisterStartupScript(
this.GetType(), "OpenWindow", "window.open('ApplicantDetails.aspx?ref_no=" + refNo + "','_blank');", true);
}
This approach does not use session state which might result in some hard to track bugs if the user clicks several of the pages. Each detail page that is opened receives the matching reference number.
In the detail page, you can use the Request object to read the parameter and fetch the corresponding data:
var refNo = Request["refNo"];
// ...
use onCommand event with command arguments, check the following code in the page
<asp:LinkButton ID="lblApplicationNo" runat="server"
Text='<%#Eval("APPL_REF_NO") %>'
OnCommand="btnApplicantDetails_Command" CommandName="ApplicantDetails"
CommandArgument='<%#Eval("APPL_REF_NO") %>'></asp:LinkButton>
and the following in the code
protected void btnApplicantDetails_Command(object sender, CommandEventArgs e)
{
string appNo = e.CommandArgument.ToString();
// do work ...
}
Write as below
<Columns>
<asp:TemplateField HeaderText="ApplicationNo">
<ItemTemplate>
<asp:LinkButton ID="lblApplicationNo" runat="server"
data-applRefNo='<%#Eval("APPL_REF_NO") %>' Text = "Application Details" OnClick="btnApplicantDetails_Click"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</columns>
protected void btnApplicantDetails_Click(object sender, EventArgs e)
{
string applRefno = btnApplicantDetails.attr("data-applRefNo");
your coding here
}
This is my GridView1. I want the latest record to be highlighted and after user click the authorization no(which user viewed the record in next page), the row will not be highlighted (means after the user view the record, the row is back to normal, no highlight no bold font).
My current progress is,
I have created new bit field in my database named ReadStatus, and defaulted to 0
Next, I need to do the onrowdatabound coding in order to implement this.
first question is, do i need to read the bit column(ReadStatus) as I read all this column?AuthorizationNo, ProductID,Name,Qty,---(ReadStatus)??
should I read ReadStatus in this code?
/ /READING RECORD FROM TABLE TRACK_ITEM
while (reader.Read())
{
MerchantProduct merchantProduct = new MerchantProduct();
merchantProduct.TxID = reader["TxID"].ToString();
merchantProduct.ProductID = reader["ProductID"].ToString();
merchantProduct.Name = reader["ProductName"].ToString();
merchantProduct.Qty = Convert.ToInt32(reader["Qty"]);
listLatestProduct.Add(merchantProduct);
}
return listLatestProduct;
second is, can anyone show me the proper way to code in onrowdatabound?
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
//Tried many code here but none is working
}
Thank you.
First you need to add one more column in ur db for ReadStatus(1/0),
then make is as hiddenfield in your aspx page.
<asp:TemplateField HeaderText="ReadStatus" Visible="false">
<ItemTemplate>
<asp:Label ID="readStatus" runat="server"></asp:Label>
<asp:HiddenField ID="readStatusHiddenField" runat="server" Value='<%#Eval("ReadStatus") %>'/>
</ItemTemplate>
</asp:TemplateField>
In your grid rowdataboun, just paste this code.It works for me
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
// searching through the rows
if (e.Row.RowType == DataControlRowType.DataRow)
{
int reading = Convert.ToInt32(((HiddenField)e.Row.FindControl("readStatusHiddenField")).Value);
if (reading == 0)
{
e.Row.BackColor = Color.LightGray;
e.Row.Font.Bold = true;
}
}
}
I have a grid view on my page and I want to allow the user to add / remove items to it. How it works, and the add functionality does work albeit probably not great, is that a user selects a product from a drop down list, then clicks Add.
This creates a new row in grid with the select Product text and ID. The GridView markup is:
<asp:GridView runat="server" ID="grdSelectedProducts" BorderWidth="1px" CellPadding="3" CellSpacing="2" AutoGenerateColumns="False" OnRowDataBound="grdSelectedProducts_OnRowDataBound" ShowHeaderWhenEmpty="True" DataKeyNames="ProductId"
OnRowCommand="grdSelectedProducts_RowCommand" OnRowDeleted="grdSelectedProducts_RowDeleted" OnRowDeleting="grdSelectedProducts_RowDeleting">
<Columns>
<asp:BoundField DataField="Product" HeaderText="Product" ReadOnly="False" />
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton runat="server" ID="linkDelete" runat="server" CommandName="Delete" CommandArgument="<%# Container.DataItemIndex %>">Remove</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="ProductId" HeaderText="ProductId" ReadOnly="False" Visible="False" />
</Columns>
</asp:GridView>
The data in the grid is bound but there is no connection to a database, as it's just the information from the drop down.
The linkDelete is where I want to allow the user to remove an item, so my question is, how can I actually delete the row? I've got the RowCommand event up which I've tried to remove it, but it just doesn't seem to work correctly as the table either 1) gets rebound with the same data as before or 2) all rows are removed due to the binding of a new DataTable. I'm missing something obvious, but this type of grid is new to me.
Any example I've seen here or on Google has been around gridviews which are databound from SQL, or some other database, which seems to make the rebinding easier. However my version doesn't use that so binding again doesn't seem to work correctly.
protected void grdSelectedProducts_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Delete")
{
if (!string.IsNullOrEmpty(e.CommandArgument.ToString()))
{
int rowIndex = Convert.ToInt32(e.CommandArgument);
grdSelectedProducts.DeleteRow(rowIndex);
CountryDataTable = (DataTable)grdSelectedProducts.DataSource;
DataTable table = CreateDataTable(false, string.Empty, string.Empty);
grdSelectedProducts.DataSource = table;
grdSelectedProducts.DataBind();
}
}
}
private DataTable CreateDataTable(bool isAddingValue, string selectedProduct, string selectedId)
{
// if isAddingValue is FALSE then it isn't from a button click to add a Product, it is just
// a call to create the datatable
DataTable dataTable = ProductDataTable;
if (!dataTable.Columns.Contains("Product"))
{
dataTable.Columns.Add("Product");
dataTable.Columns.Add("ProductId");
}
if (isAddingValue)
{
// Get the data from ViewState
DataRow dataRow;
dataRow = dataTable.NewRow();
dataRow["Product"] = selectedProduct;
dataRow["ProductId"] = selectedId;
dataTable.Rows.Add(dataRow);
}
else
{
grdSelectedProducts.DataSource = null;
grdSelectedProducts.DataSource = ProductDataTable;
grdSelectedProducts.DataBind();
}
// Save the data back to ViewState
ProductDataTable = dataTable;
return dataTable;
}
private DataTable ProductDataTable
{
get {return ViewState["ProductDataTable"] as DataTable ?? new DataTable(); }
set { ViewState["ProductDataTable"] = value; }
}
I do have the RowDeleting & RowDeleted events but I don't have any code in it.
First thing you should note is you are deleting the row from grid not from the data table
Then you again bind the data table which may not give you any change, What you should do is instead of deleting from grid delete it from datatable
Rewrite it like
if (e.CommandName == "Delete")
{
if (!string.IsNullOrEmpty(e.CommandArgument.ToString()))
{
int rowIndex = Convert.ToInt32(e.CommandArgument);
DataTable table = CreateDataTable(false, string.Empty, string.Empty);
table.Rows.RemoveAt(rowIndex)
grdSelectedProducts.DataSource = table;
grdSelectedProducts.DataBind();
}
}
If you need it to remove it from DB , DOnt forget to do that , And also note that the above code each time when u fetch the table it will give u everything from DB
so you can make it global , or you can just remove from DB
try this code
if (e.CommandName == "Delete")
{
if (!string.IsNullOrEmpty(e.CommandArgument.ToString()))
{
int rowIndex = Convert.ToInt32(e.CommandArgument);
grdSelectedProducts.DeleteRow(rowIndex);
SqlCommand cmd = new SqlCommand ("Delete from table where id='"+ rowIndex )+"'",ConnectionObject);
cmd.ExecutenonQuery();
CountryDataTable = (DataTable)grdSelectedProducts.DataSource;
DataTable table = CreateDataTable(false, string.Empty, string.Empty);
grdSelectedProducts.DataSource = table;
grdSelectedProducts.DataBind();
}
}
What am I doing wrong since the content in the < EditItemTemplate > is not displayed when I click the Edit button?
<asp:FormView runat="server" id="fwHotelDetails" DataKeyNames="id" OnDataBound="fwHotelDetails_DataBound" OnModeChanging="fwHotelDetails_ModeChanging">
<ItemTemplate>
//display content here
<asp:LinkButton ID="EditButton" runat="server" CausesValidation="False" CommandName="Edit" Text="Edit" />
</ItemTemplate>
<EditItemTemplate>
This text should be displayed when I click the Edit button
<asp:LinkButton runat="server" ID="UpDateButton" CausesValidation="false" CommandName="Update" Text="Lagre" />
</EditItemTemplate>
</asp:FormView>
Update
This is my code-behind:
namespace development.templates
{
public partial class HotelDetails : TemplatePage
{
static Hotel hotel;
protected DataRow drHotel;
DataTable dtCriteria;
DataTable dtHotel;
private HotelCriteria hotelCriteria;
protected void Page_Load(object sender, EventArgs e)
{
int hotelID = Convert.ToInt32(Request.QueryString["hotelid"].ToString());
if (!IsPostBack)
{
if (hotelID != 0)
{
// Create Hotel instance based on hoteID.
hotel = new Hotel(hotelID);
drHotel = hotel.hotelData.Rows[0];
dtHotel = hotel.getHotelsByCity(drHotel["city"].ToString());
// Hotel scrore is calculated from a score which is derived from certain criterias.
hotelCriteria = new HotelCriteria(hotelID);
dtCriteria = hotelCriteria.getHotelCriteria();
//Set datasource for hotel list in right sidebar.
hotelListByCity.DataSource = correctList(dtHotel, hotelID);
hotelListByCity.DataBind();
// Set datasource for current hotel
fwHotelDetails.DataSource = hotel.hotelData;
fwHotelDetails.DataBind();
}
}
}
protected void fwHotelDetails_DataBound(object sender, EventArgs e)
{
//Find the criteria list and set the datasource
Repeater rep = (Repeater)fwHotelDetails.FindControl("repCriteriaScore");
rep.DataSource = this.dtCriteria;
rep.DataBind();
// Controll is user is logged in. If logged in, then user may add, edit or delete hotel record.
System.Security.Principal.IPrincipal user = Context.User;
if ((user != null) && user.Identity.IsAuthenticated){
Panel panel = (Panel)fwHotelDetails.FindControl("administrationPanel");
panel.Visible = true;
}
}
protected void fwHotelDetails_ModeChanging(object sender, FormViewModeEventArgs e)
{
switch (e.NewMode)
{
case FormViewMode.Edit:
MessageLabel.Text = "Edit mode";
fwHotelDetails.ChangeMode(FormViewMode.Edit);
break;
case FormViewMode.ReadOnly:
MessageLabel.Text = "Read mode";
break;
case FormViewMode.Insert:
MessageLabel.Text = "Insert mode";
break;
}
}
}
}
The EditItemTemplate also won't show up if the record is empty. In other words, if you have a gridview that you select a detail record from that is feeding the formview, and their is no detail for the selected grid item, then the form won't show up at all. I check to see if the detail record is null, and if so, I set the formview or detailsview to "insert" mode. so they can enter a new record.
In your function fwHotelDetails_ModeChanging, add this:
fwHotelDetails.ChangeMode(FormViewMode.Edit)
i.e.
Protected Sub fwHotelDetails_ModeChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.FormViewModeEventArgs) Handles fwHotelDetails.ModeChanging
fwHotelDetails.ChangeMode(FormViewMode.Edit)
End Sub
Ok have you tried putting a breakpoint on fwHotelDetails_ModeChanging and then debugging the App? Does the breakpoint get hit when you click the edit button.
At least this will tell you where your problem lies. That is [1] the events are not hooked up correctly or [2] there is something going wrong with ChangeMode.
I realise this isnt a solution but if you tell me whether the breakpoint hits i can help you further.
I am using ASP.NET with C# and subsonic.
I am trying to setup a search on a text field by first and last name.
First or Last Name: <asp:TextBox ID="txtSearchName" runat="server"></asp:TextBox>
<asp:linkButton runat="server" Text="Send" onclick="btnSubmit_Click" />
<asp:GridView
border="0"
cellpadding="3"
cellspacing="3"
ShowHeader="True"
allowsorting="true"
ID="GridView1"
runat="server"
AutoGenerateColumns="false"
Visible="false"
AllowPaging="True"
PageSize="10"
PagerStyle-Mode="NumericPages"
OnPageIndexChanging="GridView1_PageIndexChanging"
>
In the code behind, I have this:
private void BuildGridView1()
{
GridView1.DataSource = new Select(PastAwardName.Schema.TableName + ".*", PastAwardType.Schema.TableName + ".*")
.From(PastAwardName.Schema)
.InnerJoin(PastAwardType.Schema.TableName, PastAwardType.Columns.VolID, PastAwardName.Schema.TableName, PastAwardName.Columns.VolID)
.Where(PastAwardName.Columns.LName).IsEqualTo(this.txtSearchName.Text)
.Or(PastAwardName.Columns.FName).IsEqualTo(this.txtSearchName.Text)
.OrderAsc(PastAwardType.Columns.AwardYear)
.ExecuteDataSet();
}
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
BuildGridView1();
GridView1.PageIndex = e.NewPageIndex;
GridView1.DataBind();
}
This works if you enter either the first or last name, but I want to be able to search for them both at the same time from one text field. Is this possible?
You should be able to build your query and then append the Or/And restrictions based on whether you have more than one name. The following should work but you should be aware that edge cases like double-barelled names, a user entering a middle name etc. will catch you out:
private void BuildGridView1()
{
string[] names = this.txtSearchName.Text.Split(" ".ToCharArray());
SqlQuery query = DB.Select(PastAwardName.Schema.TableName + ".*", PastAwardType.Schema.TableName + ".*")
.From(PastAwardName.Schema)
.InnerJoin(PastAwardType.Schema.TableName, PastAwardType.Columns.VolID, PastAwardName.Schema.TableName, PastAwardName.Columns.VolID)
.Where(PastAwardName.Columns.FName).IsEqualTo(names[0])
if(names.Length > 1)
query = query.And(PastAwardName.Columns.LName).IsEqualTo(names[1])
else
query = query.Or(PastAwardName.Columns.LName).IsEqualTo(names[0]
GridView1.DataSource = query.OrderAsc(PastAwardType.Columns.AwardYear)
.ExecuteDataSet();
}
Split the contents of this.txtSearchName.Text, if it contains one word use your original query, if it contains two words, then use a modified version of your query:
private void BuildGridView1()
{
string[] names = String.Split(this.txtSearchName.Text, ' ');
if (names.length == 1) {
GridView1.DataSource = new Select(PastAwardName.Schema.TableName + ".*", PastAwardType.Schema.TableName + ".*")
.From(PastAwardName.Schema)
.InnerJoin(PastAwardType.Schema.TableName, PastAwardType.Columns.VolID, PastAwardName.Schema.TableName, PastAwardName.Columns.VolID)
.Where(PastAwardName.Columns.LName).IsEqualTo(names[0])
.Or(PastAwardName.Columns.FName).IsEqualTo(names[0])
.OrderAsc(PastAwardType.Columns.AwardYear)
.ExecuteDataSet();
}
else if (names.Length == 2) {
GridView1.DataSource = new Select(PastAwardName.Schema.TableName + ".*", PastAwardType.Schema.TableName + ".*")
.From(PastAwardName.Schema)
.InnerJoin(PastAwardType.Schema.TableName, PastAwardType.Columns.VolID, PastAwardName.Schema.TableName, PastAwardName.Columns.VolID)
.Where(PastAwardName.Columns.LName).IsEqualTo(names[1])
.And(PastAwardName.Columns.FName).IsEqualTo(names[0])
.OrderAsc(PastAwardType.Columns.AwardYear)
.ExecuteDataSet();
}
}
You'll probably also want to add error handling/validation for the case when the user does not enter a value in the text box or enters 3 or more words.