I am developing a GridView that allow editing. I want to disable the warning message of data loss. However its not working.
For example, I edit some field without click the "Save Changes" and then click the column header for sorting, the warning message "Are you sure you want to perform the action? All unsaved grid data will be lost." still alert.
How could I solve this problem?
Here are my sample codes:
TestingWeb.aspx
<form id="form1" runat="server">
<dx:ASPxGridView ID="ASPxGridView1" runat="server" KeyFieldName="Line" OnRowUpdating="ASPxGridView1_RowUpdating">
<Columns>
<dx:GridViewDataTextColumn Caption="Line" FieldName="Line" Name="col_Line" ReadOnly="True" VisibleIndex="1">
</dx:GridViewDataTextColumn>
<dx:GridViewDataTextColumn Caption="Text" FieldName="Text" Name="col_Text" VisibleIndex="2">
</dx:GridViewDataTextColumn>
</Columns>
<SettingsEditing Mode="Batch" BatchEditSettings-ShowConfirmOnLosingChanges="false"></SettingsEditing>
</dx:ASPxGridView>
</form>
TestingWeb.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
DataTable DT = new DataTable();
DT.Columns.Add("Line");
DT.Columns.Add("Text");
DataRow r = DT.NewRow();
r["Line"] = 1;
r["Text"] = "Test";
DT.Rows.Add(r);
DataColumn[] key = new DataColumn[1];
key[0] = DT.Columns["Line"];
DT.PrimaryKey = key;
ASPxGridView1.DataSource = DT;
ASPxGridView1.DataBind();
Session["DataTable"] = DT;
}
protected void ASPxGridView1_RowUpdating(object sender, DevExpress.Web.Data.ASPxDataUpdatingEventArgs e)
{
DevExpress.Web.ASPxGridView.ASPxGridView gridView = (DevExpress.Web.ASPxGridView.ASPxGridView)sender;
DataTable DT = (DataTable)(Session["DataTable"]);
DataRow row = DT.Rows.Find(e.Keys[0]);
IDictionaryEnumerator enumerator = e.NewValues.GetEnumerator();
enumerator.Reset();
while (enumerator.MoveNext())
{
row[enumerator.Key.ToString()] = enumerator.Value;
}
gridView.CancelEdit();
e.Cancel = true;
Session["DataTable"] = DT;
}
I updated the version to 13.2.6 and the problem is solved.
Related
Please find image. Here's my whole code, I wanted save each row on save button click. I'm able to get value from cell 0 and cell 1 but unable to get value from cell 2 , where I have drop down list selected value.I'm getting default value "Ignore" instead of selected item. So how do I get selected value of drop down list ?
<div>
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns = "False"
OnRowDataBound = "OnRowDataBound" Width="544px">
<Columns>
<asp:BoundField DataField="Id" HeaderText="Id" />
<asp:BoundField HeaderText="Name" DataField="Name" />
<asp:TemplateField HeaderText = "Mapping" >
<ItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server" style="font-size: medium; font-family: Cambria" Width="300px">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<br />
<asp:Button ID="Button2" runat="server" Text="Save"
style="font-size: medium; font-family: Cambria" BorderStyle="Groove"
height="32px" Width="116px" onclick="Save_Click" />
</div>
private void BindGrid()
{
DataTable dt = new DataTable();
connection();
cmd = new SqlCommand("Select top 0 * from F3_BC_Product_Mapping_Data", con);
con.Open();
adapter = new SqlDataAdapter(cmd);
ds = new DataSet();
adapter.Fill(ds, "mytable");
int j = 1;
dt.Columns.AddRange(new DataColumn[2] { new DataColumn("Id", typeof(int)), new DataColumn("Name", typeof(string)) });
foreach (DataColumn column in ds.Tables[0].Columns)
{
dt.Rows.Add(j,column.ColumnName);
j++;
}
GridView2.DataSource = dt;
GridView2.DataBind();
con.Close();
}
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList ddlMap = (e.Row.FindControl("DropDownList1") as DropDownList);
DataTable dt = new DataTable();
dt = (DataTable)Session["data"];
for (int i = 0; i < dt.Columns.Count; i++)
{
ddlMap.Items.Add(dt.Columns[i].Caption.ToString());
}
ddlMap.Items.Insert(0, new ListItem("Ignore"));
}
}
protected void Save_Click(object sender, EventArgs e)
{
foreach (GridViewRow gr in GridView2.Rows)
{
string cell_1_Value = GridView2.Rows[gr.RowIndex].Cells[0].Text;
string cell_2_Value = GridView2.Rows[gr.RowIndex].Cells[1].Text;
string cell_3_Value = ((DropDownList)gr.FindControl("DropDownList1")).SelectedItem.Value;
}
}
If you are getting default value then you must see binding code. I think you haven't use if(!Page.IsPostBack) before binding and setting default value in drop down. Try to change OnRowDataBound as below.
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow && !Page.IsPostBack)
{
DropDownList ddlMap = (e.Row.FindControl("DropDownList1") as DropDownList);
DataTable dt = new DataTable();
dt = (DataTable)Session["data"];
for (int i = 0; i < dt.Columns.Count; i++)
{
ddlMap.Items.Add(dt.Columns[i].Caption.ToString());
}
ddlMap.Items.Insert(0, new ListItem("Ignore"));
}
}
i have a gridview in a asp.net webform and i add it a check box column like this (the dataTable first column(0) is empty in sql data source and i add check boxes on the column cells):
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (rowNum != 0)//except first row
{
CheckBox cb = new CheckBox();
cb.Enabled = true;
e.Row.Cells[0].Controls.Add(cb);//row[0]=first clmn-and this event happend for all rows
}
rowNum++;
}
now i have a dynamic check box column! and user should check some of them and click the submit then i need the row number of the checked check boxes.
how can i do this?
i tried this before:
DataTable editTable = new DataTable();
editTable.Rows.Add(GridView1.Rows[0]);
var x = editTable.Rows[0][0];
but the x cannot get the check box true or false! it seems that getting me the original field under the check box content.
regards.
Instead of creating the controls dynamically which in most cases results in a lot of trouble, you could add the CheckBoxes in one or more template columns. The following sample shows how to add a checkbox in a template column and how to retrieve the value afterwards:
<asp:GridView ID="gridView" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="chb" runat="server" />
<asp:HiddenField ID="hiddenId" runat="server"
Value='<%# DataBinder.Eval(Container.DataItem, "Id") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Text" />
</Columns>
</asp:GridView>
In my sample, I've bound some data to the GridView:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
var dt = GetData();
gridView.DataSource = dt;
gridView.DataBind();
}
}
private DataTable GetData()
{
var dt = new DataTable();
dt.Columns.Add("Id", typeof(int));
dt.Columns.Add("Text", typeof(string));
for (int i = 0; i < 10; i++)
dt.Rows.Add(new object[] { i, "Test text " + i.ToString() });
return dt;
}
If you need to set the value, you can do so in the RowDatabound event. The following code shows how to retrieve the value of the Checkbox controls:
protected void btn_Click(object sender, EventArgs e)
{
List<int> checkedIds = new List<int>();
foreach(GridViewRow row in gridView.Rows.OfType<GridViewRow>()
.Where(x => x.RowType == DataControlRowType.DataRow))
{
var hiddenId = (HiddenField)row.Cells[0].FindControl("hiddenId");
var checkBox = (CheckBox) row.Cells[0].FindControl("chb");
if (checkBox.Checked)
checkedIds.Add(int.Parse(hiddenId.Value));
}
}
What i am trying to do is that before saving records to database i want to show the records in GridView that is when user fill the text box and click on button the record is to be shown on GridView with serial Number 1 , 2 , 3 ...
So far i have approach this . The first records get added successfully but when adding second record the DataTable give null reference exception . Is this the right approach ? Or is there an easy way to do this . I am using Telerik RadGrid for asp.net .
public DataTable dt;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
dt = new DataTable();
dt.Columns.Add("Sn#");
dt.Columns.Add("type");
dt.Columns.Add("AccountTitle");
dt.Columns.Add("Description");
dt.Columns.Add("CostCenter");
dt.Columns.Add("Debit");
dt.Columns.Add("Credit");
sno.Text = "1";
}
}
protected void radGridView2_NeedDataSource(object sender, GridNeedDataSourceEventArgs e)
{
dt = AddRow(dt); // call the method to create row
ViewState["dt"] = dt;
dt = (DataTable)ViewState["dt"];
radGridView2.DataSource = dt;
}
private DataTable AddRow(DataTable dt)
{ // method to create row
DataRow dr = dt.NewRow();
dr[0] = sno.Text;
dr[1] = type.Text;
dr[2] = htitle.Text;
dr[3] = disc.Text;
dr[4] = job.SelectedItem.Text;
dr[5] = drr.Text;
dr[6] = crr.Text;
dt.Rows.Add(dr);
return dt;
}
protected void b1_Click(object sender, EventArgs e)
{
DataTable dt = (DataTable)ViewState["dt"];
ViewState["dt"] = AddRow(dt);
radGridView2.Rebind();
Session["cttt"] = Convert.ToInt32(sno.Text)+1;
sno.Text = Session["cttt"].ToString();
}
I have copy your code and change a bit. Due to your dt declared twice. I believe your error will be the DataTable is null
.aspx
<asp:ScriptManager ID="sm" runat="server"></asp:ScriptManager>
<div>
<telerik:RadGrid ID="rg" runat="server" OnNeedDataSource="RadGrid1_NeedDataSource"></telerik:RadGrid>
<br />
<asp:TextBox ID="sno" runat="server"></asp:TextBox><br />
<asp:TextBox ID="type" runat="server" Text="A"></asp:TextBox><br />
<asp:TextBox ID="htitle" runat="server" Text="B"></asp:TextBox><br />
<asp:TextBox ID="disc" runat="server" Text="C"></asp:TextBox><br />
<asp:DropDownList ID="job" runat="server"><asp:ListItem>Yeah</asp:ListItem></asp:DropDownList><br />
<asp:TextBox ID="drr" runat="server" Text="D"></asp:TextBox><br />
<asp:TextBox ID="crr" runat="server" Text="E"></asp:TextBox><br />
<br />
<br />
<asp:Button ID="b1" runat="server" Text="Click" OnClick="b1_Click" />
</div>
</asp:ScriptManager>
.cs
private DataTable dt;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
sno.Text = "1";
}
}
private DataTable CreateDataTable()
{
dt = new DataTable();
dt.Columns.Add("Sn#");
dt.Columns.Add("type");
dt.Columns.Add("AccountTitle");
dt.Columns.Add("Description");
dt.Columns.Add("CostCenter");
dt.Columns.Add("Debit");
dt.Columns.Add("Credit");
return dt;
}
private DataTable AddRow(DataTable dt1)
{ // method to create row
DataRow dr = dt1.NewRow();
dr[0] = sno.Text;
dr[1] = type.Text;
dr[2] = htitle.Text;
dr[3] = disc.Text;
dr[4] = job.SelectedItem.Text;
dr[5] = drr.Text;
dr[6] = crr.Text;
dt1.Rows.Add(dr);
return dt1;
}
protected void RadGrid1_NeedDataSource(object sender, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
{
rg.DataSource = ViewState["dt"] as DataTable;
}
protected void b1_Click(object sender, EventArgs e)
{
DataTable dt1 = ViewState["dt"] != null ? ViewState["dt"] as DataTable : CreateDataTable();
ViewState["dt"] = AddRow(dt1);
rg.Rebind();
Session["cttt"] = Convert.ToInt32(sno.Text) + 1;
sno.Text = Session["cttt"].ToString();
}
Result
You are creating a variable with the same name as the global variable (dt) in the event b1_click - this is causing the confusion and the error.
protected void b1_Click(object sender, EventArgs e)
{
//Use the global variable dt
//DataTable dt = (DataTable)ViewState["dt"];
dt = (DataTable)ViewState["dt"];
ViewState["dt"] = AddRow(dt);
radGridView2.Rebind(); //Note this would call the NeedDataSource event
Session["cttt"] = Convert.ToInt32(sno.Text)+1;
sno.Text = Session["cttt"].ToString();
}
Another point to note here is that the AddRow method will be called twice on the button click. Once from b1_click event and then again from NeedDataSource event (which gets triggered on radGridView2.Rebind())
I have an editable GridView, which has a AddRow button, on click of which an empty row consisting of text boxes is added.
Whenever I insert values inside these textboxes, and click AddRow or Delete button, the text boxes loose their values.
I am sure, this doesn't happen due to postback, because there's a Save button too, on the click of which the values are normally preserved.
Below is the markup:
<asp:GridView ID="GridView1" runat="server" ShowFooter="true" AutoGenerateColumns="false"
OnRowDeleting="GridView1_RowDeleting">
<Columns>
<asp:TemplateField HeaderText="Col1">
<ItemTemplate>
<asp:TextBox runat="server" ID="txt1"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Col2">
<ItemTemplate>
<asp:TextBox ID="txt2" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Col3">
<ItemTemplate>
<asp:TextBox ID="txt3" runat="server"></asp:TextBox>
</ItemTemplate>
<FooterStyle HorizontalAlign="Right" />
<FooterTemplate>
<asp:Button ID="btnAddNewRow" runat="server" Text="AddRow" OnClick="Add" />
</FooterTemplate>
</asp:TemplateField>
<asp:CommandField ButtonType="Button" ShowDeleteButton="true" />
</Columns>
</asp:GridView>
<asp:Button ID="btnSavetoDB" runat="server" Text="save" OnClick="btnSavetoDB_Click" />
Code Behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
SetInitialRow();
}
}
//Sets the first empty row to the grid view
private void SetInitialRow()
{
DataTable dt = new DataTable();
DataRow dr = null;
dt.Columns.Add(new DataColumn("Column1", typeof(string)));
dt.Columns.Add(new DataColumn("Column2", typeof(string)));
dt.Columns.Add(new DataColumn("Column3", typeof(string)));
dr = dt.NewRow();
dr["Column1"] = string.Empty;
dr["Column2"] = string.Empty;
dr["Column3"] = string.Empty;
dt.Rows.Add(dr);
//Store the DataTable in ViewState
ViewState["CurrentTable"] = dt;
GridView1.DataSource = dt;
GridView1.DataBind();
}
//Adds a new empty row to the grid view
protected void Add(object sender, EventArgs e)
{
int rowIndex = 0;
if (ViewState["CurrentTable"] != null)
{
DataTable dtCurrentTable = (DataTable)ViewState["CurrentTable"];
DataRow drCurrentRow = null;
if (dtCurrentTable.Rows.Count > 0)
{
for (int i = 0; i < dtCurrentTable.Rows.Count; i++)
{
//extract the TextBox values
TextBox box1 = (TextBox)GridView1.Rows[rowIndex].Cells[0].FindControl("txt1");
TextBox box2 = (TextBox)GridView1.Rows[rowIndex].Cells[1].FindControl("txt2");
TextBox box3 = (TextBox)GridView1.Rows[rowIndex].Cells[2].FindControl("txt3");
drCurrentRow = dtCurrentTable.NewRow();
//drCurrentRow["RowNumber"] = i + 1;
drCurrentRow["Column1"] = box1.Text;
drCurrentRow["Column2"] = box2.Text;
drCurrentRow["Column3"] = box3.Text;
rowIndex++;
}
//add new row to DataTable
dtCurrentTable.Rows.Add(drCurrentRow);
//Store the current data to ViewState
ViewState["CurrentTable"] = dtCurrentTable;
//Rebind the Grid with the current data
GridView1.DataSource = dtCurrentTable;
GridView1.DataBind();
}
}
else
{
Response.Write("ViewState is null");
}
}
//Called on Delete Button click, which is inside a CommanField
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
int num = GridView1.Rows.Count;
int index = Convert.ToInt32(e.RowIndex);
if (num > 1)
{
DataTable dt = ViewState["CurrentTable"] as DataTable;
dt.Rows[index].Delete();
ViewState["CurrentTable"] = dt;
GridView1.DataSource = dt;
GridView1.DataBind();
}
}
Initial snapshot:
After AddRow button click:
Where am I going wrong?
Experts please help.
Regards
The problem is that you haven't used Eval in your markup
<asp:TextBox runat="server" ID="txt1" Text='<%# Eval("Column1") %>'></asp:TextBox>
Optimized code-behind. No need of ViewState
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
var table = CreateDataTable();
table.Rows.Add("", "", "");
BindGridView(table);
}
}
//Sets the first empty row to the grid view
private DataTable CreateDataTable()
{
var dt = new DataTable
{
Columns = { "Column1", "Column2", "Column3" }
};
return dt;
}
private void BindGridView(DataTable table)
{
GridView1.DataSource = table;
GridView1.DataBind();
}
private DataTable PopulateTableFromGridView()
{
var table = CreateDataTable();
for (int i = 0; i < GridView1.Rows.Count; i++)
{
//extract the TextBox values
TextBox box1 = (TextBox)GridView1.Rows[i].FindControl("txt1");
TextBox box2 = (TextBox)GridView1.Rows[i].FindControl("txt2");
TextBox box3 = (TextBox)GridView1.Rows[i].FindControl("txt3");
table.Rows.Add(box1.Text, box2.Text, box3.Text);
}
return table;
}
//Adds a new empty row to the grid view
protected void Add(object sender, EventArgs e)
{
var newTable = PopulateTableFromGridView();
newTable.Rows.Add("", "", "");
BindGridView(newTable);
}
//Called on Delete Button click, which is inside a CommanField
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
var dt = PopulateTableFromGridView();
dt.Rows[e.RowIndex].Delete();
if (dt.Rows.Count == 0)
{
dt.Rows.Add("", "", "");
}
BindGridView(dt);
}
Links on inline expressions
http://support.microsoft.com/kb/976112
http://weblogs.asp.net/ahmedmoosa/embedded-code-and-inline-server-tags
Good day!
I need to dynamycally upload files and display information in gridview.
After file upload, i need to select file type in dropdown.
But after postback i can't access Gridview1 rows, and get selected file types. After postback Gridview1.Rows.Count = 0.
Is it possible to get selected values from DropDownLists?
<asp:GridView ID="GridView1" runat="server" ShowHeader="False" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="FileName" />
<asp:TemplateField HeaderText="FileType">
<ItemTemplate>
<asp:DropDownList runat="server">
<asp:ListItem Value="Val1">Val1</asp:ListItem>
<asp:ListItem Value="Val2">Val2</asp:ListItem>
<asp:ListItem Value="Val3">Val3</asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField DeleteText="Remove" ShowDeleteButton="true" />
</Columns>
</asp:GridView>
<asp:FileUpload ID="FileUpload" runat="server" onchange="this.form.submit()" />
Thanks
In Page_Load, during PostBack, GridView rows is empty.
protected void Page_Load(object sender, EventArgs e)
{
RestoreForm();
if (IsPostBack && FileUpload.HasFile)
{
AddRow(FileUpload.PostedFile.FileName);
}
FilesGridView.RowDeleting += new GridViewDeleteEventHandler(RemoveFileFromTable);
}
private void AddRow(string file)
{
DataTable dt = (DataTable)Page.Session["Files"];
if (dt == null)
{
AddDataTableToSession();
dt = (DataTable)Page.Session["Files"];
}
DataRow dr = dt.NewRow();
dr["FileName"] = file;
dr["FileType"] = 0;
dt.Rows.Add(dr);
Page.Session["Files"] = dt;
FilesGridView.DataSource = dt;
FilesGridView.DataBind();
}
private void AddDataTableToSession()
{
DataTable dt = new DataTable("Files");
DataColumn dc = new DataColumn("FileName", Type.GetType("System.String"));
dt.Columns.Add(dc);
dc = new DataColumn("FileType", Type.GetType("System.String"));
dt.Columns.Add(dc);
Page.Session["Files"] = dt;
}
private void RemoveFileFromTable(object sender, GridViewDeleteEventArgs e)
{
int recordToDelete = e.RowIndex;
DataTable dt = (DataTable)Page.Session["Files"];
int cn = dt.Rows.Count;
dt.Rows.RemoveAt(recordToDelete);
dt.AcceptChanges();
Page.Session["Files"] = dt;
FilesGridView.DataSource = dt;
FilesGridView.DataBind();
}
Try by changing Ispostback like this.
if (!IsPostBack && FileUpload.HasFile)
{
AddRow(FileUpload.PostedFile.FileName);
}
(or)
if (IsPostBack == false && FileUpload.HasFile)
{
AddRow(FileUpload.PostedFile.FileName);
}
So that, if page load occurs, Your if condition will get true.
You can find the drop down list and update it with the value in the RowDataBOund event of gridview as follows
protected void Page_Load(object sender, EventArgs e)
{
//RestoreForm();
if (IsPostBack && FileUpload.HasFile)
{
AddRow(FileUpload.PostedFile.FileName);
}
else
{
AddDataTableToSession();
}
FilesGridView.RowDeleting += new GridViewDeleteEventHandler(RemoveFileFromTable);
FilesGridView.RowDataBound += KBFilesGridView_RowDataBound;
}
and row databound will be as follows
void KBFilesGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
DropDownList ddl = e.Row.FindControl("DropDownList1") as DropDownList;
if (ddl != null)
{
DataRow dr= ((DataRowView)e.Row.DataItem).Row;
ddl.SelectedValue = dr["FileType"].ToString();
}
}
Similary you can get the value of dropdown for remove method as well as follows
private void RemoveFileFromTable(object sender, GridViewDeleteEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList ddl = e.Row.FindControl("DropDownList1") as DropDownList;
if (ddl != null)
{
if(ddl.SelectedValue == "someValue") doSomeThing();
}
}
}