I've added an edit/update option to a Gridview of bound data from a table in my database TextBooks. I'm allowing this in case something changes down the road the admin can then edit/update the information. Currently I am able to click edit type in the information, and then it binds it to the current Grid on page, but doesn't save it to the database and upon leaving the page and returning to it, it is reverted back to the old value. After following the code to the BindGrid() method i believe I've gone wrong somewhere but cannot fully grasp what it is I'm missing.
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
DataTable dt = new DataTable();
string query = "select * from textBooks ";
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["HUTDMSConnectionString"].ToString()))
using (SqlDataAdapter adapter = new SqlDataAdapter(query, connection))
adapter.Fill(dt);
ViewState["allBooks"] = dt;
this.BindGrid();
}
}
protected void BindGrid()
{
GridView1.DataSource = ViewState["allBooks"] as DataTable;
GridView1.DataBind();
}
protected void OnRowEditing(object sender, GridViewEditEventArgs e)
{
GridView1.EditIndex = e.NewEditIndex;
this.BindGrid();
}
protected void OnUpdate(object sender, EventArgs e)
{
GridViewRow row = (sender as LinkButton).NamingContainer as GridViewRow;
string Ancillary = (row.Cells[3].Controls[0] as TextBox).Text;
string BookActive = (row.Cells[4].Controls[0] as TextBox).Text;
string InactiveDate = (row.Cells[6].Controls[0] as TextBox).Text;
string Author = (row.Cells[7].Controls[0] as TextBox).Text;
string Publisher = (row.Cells[8].Controls[0] as TextBox).Text;
string EditionAndDate = (row.Cells[9].Controls[0] as TextBox).Text;
string Imprint = (row.Cells[10].Controls[0] as TextBox).Text;
string eISBN = (row.Cells[13].Controls[0] as TextBox).Text;
string ebookAvailable = (row.Cells[14].Controls[0] as TextBox).Text;
string Notes = (row.Cells[15].Controls[0] as TextBox).Text;
DataTable dt = ViewState["allBooks"] as DataTable;
dt.Rows[row.RowIndex]["Ancillary"] = Ancillary;
dt.Rows[row.RowIndex]["BookActive"] = BookActive;
dt.Rows[row.RowIndex]["InactiveDate"] = InactiveDate;
dt.Rows[row.RowIndex]["Author"] = Author;
dt.Rows[row.RowIndex]["Publisher"] = Publisher;
dt.Rows[row.RowIndex]["EditionAndDate"] = EditionAndDate;
dt.Rows[row.RowIndex]["Imprint"] = Imprint;
dt.Rows[row.RowIndex]["eISBN"] = eISBN;
dt.Rows[row.RowIndex]["ebookAvailable"] = ebookAvailable;
dt.Rows[row.RowIndex]["Notes"] = Notes;
ViewState["allBooks"] = dt;
GridView1.EditIndex = -1;
this.BindGrid();
}
So what you are currently doing is pulling data from a database, storing it in a gridview, then editing the data in the GridView. Once you call that databind command, that data becomes independent from the Database. In order to save this data to the database, I would recommend using SqlDataAdapter's Update method in the OnUpdate method. This will allow you to store the update values back to a datarow and save it to the database while following a similar strategy as when you fill the GridView.
Related
I have data in a DataTable object and I want to retrieve specific data from a data table on some certain conditions, for to query a data table using its select method
My database is MySQL 8.0.17 version
I tried this code without success because the error on VS 2019 is
The [ABW] column could not be found string
But the [ABW] don't is the name of column but value of column CountryCode
What's wrong with this code?
Please, any help?
DataTable cgv = new DataTable();
DataTable dtCustomers;
DataTable dtOrders;
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
// Create a datatable as a DataSource of GridViews
dtCustomers = new DataTable(); // parent gridview datasource
dtOrders = new DataTable(); // child gridview datasource
dtOrders = GetData("SELECT CountryCode, Language, IsOfficial, Percentage FROM `tCustomers`");
cgv = dtOrders; // set child datatable to temporary datatable
dtCustomers = GetData("SELECT CountryCode, Language, IsOfficial, Percentage FROM `tCustomers`;");
gvCustomers.DataSource = dtCustomers;
gvCustomers.DataBind();
}
}
protected void gvCustomers_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string CountryCode = gvCustomers.DataKeys[e.Row.RowIndex].Value.ToString();
GridView gvOrders = ((GridView)e.Row.FindControl("gvOrders"));
dtOrders.Columns[0].ColumnName = "CountryCode";
DataRow[] dr = dtOrders.Select(dtOrders.Columns[0].ColumnName + "=" + CountryCode.ToString());
gvOrders.DataSource = dr; // set child datatable to parent gridview as datasource
gvOrders.DataBind();
}
}
Like this:
protected void gvParent_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string CountryCode = gvCustomers.DataKeys[e.Row.RowIndex].Value.ToString();
GridView gvOrders = ((GridView)e.Row.FindControl("gvOrders"));
cgv.DefaultView.RowFilter = "CountryCode='" + CountryCode.ToString() + "'";
gvOrders.DataSource = cgv;
gvOrders.DataBind();
}
}
EDIT: added a code and a image reference `public partial class DodavanjeNamirnice : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
DataTable dtTemp = new DataTable(); ;
dtTemp.Columns.Add(new DataColumn("Namirnica", typeof(string)));
dtTemp.Columns.Add(new DataColumn("Mjerna Jedinica", typeof(string)));
Session["Data"] = dtTemp;
}
}
protected void BindGrid()
{
string constr = ConfigurationManager.ConnectionStrings["Data Source =.\\SQLEXPRESS; Initial Catalog = pra; Integrated Security = True"].ConnectionString;
string query = "SELECT * FROM Namirnica";
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlDataAdapter sda = new SqlDataAdapter(query, con))
{
using (DataTable dt = new DataTable())
{
sda.Fill(dt);
GridView1.DataSource = dt;
GridView1.DataBind();
}
}
}
}
protected void btnAdd_Click(object sender, EventArgs e)
{
var dataTableFromSession = Session["Data"] as DataTable;
var dataRow = dataTableFromSession.NewRow();
dataRow["Namirnica"] = DropDownList2.SelectedItem.Text;
dataRow["Mjerna Jedinica"] = CheckBoxList1.SelectedItem.Text;
dataTableFromSession.Rows.Add(dataRow);
Session["Data"] = dataTableFromSession;
GridView1.DataSource = dataTableFromSession;
GridView1.DataBind();
}
}`I got 2 dropdownlists , first one is filtering data in the 2nd,also 1st dropdownlist is connected to sql table as is the other one.
I have a checkbox which displays data from another table.
And my problem is: I want to add values I selected from 2nd dropdownlist and the checkboxlist to gridview in my webform.
I tried adding new columns manually but that ends up with displaying only first value from the dropdownlist, also displays only one value from the checkboxlist.
https://gyazo.com/59ea939b26deb55d3f31e68057249253
Set up a method to change the selected or created cell into a DataGridViewComboBoxCell and then feed it the datasource of your drop down list.
//could be whatever event you want such as the creation of a new DataRow in your DataGridView
private void gridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
dataGridView1[e.ColumnIndex, e.RowIndex] = new DataGridViewComboBoxCell();
DataGridViewComboBoxCell cb = (DataGridViewComboBoxCell)dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];
cb.DataSource = dataSource;
}
You can do a similar thing for the checkbox but new DataGridViewCheckBoxCell() instead. After the user has selected a value you can just switch it back to being a regular cell if wanted.
I have a dropdownlist in a gridview and when the textbox is changed, I would like the selected value in the dropdownlists (three separate ones in total) to match the data in the database. The code in the textbox changed event is below:
protected void TextBox1_TextChanged(object sender, EventArgs e)
{
DropDownList ddl = new DropDownList();
string connectionString = ConfigurationManager.ConnectionStrings["*******"].ConnectionString;
using (SqlConnection con = new SqlConnection(connectionString))
{
string query = "SELECT one, two, three FROM table WHERE id = " + TextBox1.Text;
SqlDataAdapter sda = new SqlDataAdapter(query, con);
DataSet ds = new DataSet();
int num = sda.Fill(ds);
if (num > 0)
{
GridView1.Visible = true;
GridView1.DataSource = ds;
GridView1.DataBind();
}
else
{
if (num == 0)
{
GridView1.Visible = false;
}
else
{
BindGrid();
}
}
}
Try using the RowDataBound event. For this to work, the drop-down-lists must already be populated with values, and in the event, the SelectedValue will be assigned.
protected void GridView1_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// this assumes the drop-down-list columns are the first, second, and third columns (ordinal positions 0, 1, and 2)
DropDownList ddl1, ddl2, ddl3;
ddl1 = (DropDownList)e.Row.Cells[0].Controls[0];
ddl2 = (DropDownList)e.Row.Cells[1].Controls[0];
ddl3 = (DropDownList)e.Row.Cells[2].Controls[0];
DataRow currentRow = (DataRow)e.Row.DataItem;
ddl1.SelectedValue = currentRow[0].ToString();
ddl2.SelectedValue = currentRow[1].ToString();
ddl3.SelectedValue = currentRow[2].ToString();
}
}
I have an editable Gridview, its data is stored in an XML file, when I attempt to insert / update / delete data to/from the Gridview, I get the following error:
Unable to cast object of type 'System.Data.DataTable' to type 'System.Data.DataSet
The Gridview successfully displays the data that is stored in the xml file, but errors out when I attempt to insert / update / delete rows.
Could I gets some direction as to what I'm missing here?
XML file:
<root>
<pos>
<partNumbers>
<partid>0</partid>
<partnumber>796542</partnumber>
</partNumbers>
<partNumbers>
<partid>1</partid>
<partnumber>225614</partnumber>
</partNumbers>
<partNumbers>
<partid>2</partid>
<partnumber>123457</partnumber>
</partNumbers>
</pos>
</root>
My C# code:
//Bind Data
protected void BindGridView()
{
DataSet dsgvPartNumber = new DataSet();
dsgvPartNumber.ReadXml(Server.MapPath("~/xml/storeUserInfo.xml"));
gvPartNumber.DataSource = dsgvPartNumber.Tables["partNumbers"];
gvPartNumber.DataBind();
gvPartNumber.ShowFooter = true;
}
// Delete Row
protected void gvPartNumber_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
BindGridView();
DataSet dsgvPartNumberDelete = (DataSet)gvPartNumber.DataSource;
dsgvPartNumberDelete.Tables[0].Rows[gvPartNumber.Rows[e.RowIndex].DataItemIndex].Delete();
dsgvPartNumberDelete.WriteXml(Server.MapPath("~/xml/storeUserInfo.xml"));
BindGridView();
}
// EditGridView
protected void gvPartNumber_RowEditing(object sender, GridViewEditEventArgs e)
{
gvPartNumber.ShowFooter = false;
gvPartNumber.EditIndex = e.NewEditIndex;
BindGridView();
}
// Update GridView
protected void gvPartNumber_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
int index = gvPartNumber.Rows[e.RowIndex].DataItemIndex;
string partId = ((TextBox)gvPartNumber.Rows[e.RowIndex].FindControl("txtPartID")).Text;
string partNumber = ((TextBox)gvPartNumber.Rows[e.RowIndex].FindControl("txtPartNumber")).Text;
gvPartNumber.EditIndex = -1;
BindGridView();
DataSet dsUpdateXMLFile = (DataSet)gvPartNumber.DataSource;
dsUpdateXMLFile.Tables[0].Rows[index]["partid"] = partId;
dsUpdateXMLFile.Tables[0].Rows[index]["partnumber"] = partNumber;
dsUpdateXMLFile.WriteXml(Server.MapPath("~/xml/storeUserInfo.xml"));
BindGridView();
}
// Insert New Row
protected void gvPartNumber_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "insertXMLData")
{
string partid = ((TextBox)gvPartNumber.FooterRow.FindControl("txtPartIDInsert")).Text;
string partnumber = ((TextBox)gvPartNumber.FooterRow.FindControl("txtPartNumberInsert")).Text;
BindGridView();
DataSet dsXMLInsert = (DataSet)gvPartNumber.DataSource;
DataRow drInsert = dsXMLInsert.Tables[0].NewRow();
drInsert["partid"] = partid;
drInsert["partnumber"] = partnumber;
dsXMLInsert.Tables[0].Rows.Add(drInsert);
dsXMLInsert.WriteXml(Server.MapPath("~/xml/storeUserInfo.xml"));
BindGridView();
}
}
Could I please get some direction/explanation as to what I'm missing in the code?
Thank you in advance.
It's because you're setting the DataSource to a DataTable:
gvPartNumber.DataSource = dsgvPartNumber.Tables["partNumbers"];
not a DataSet. So, instead of this:
DataSet dsgvPartNumberDelete = (DataSet)gvPartNumber.DataSource;
do this:
DataTable dsgvPartNumberDelete = (DataTable)gvPartNumber.DataSource;
and then in the following lines you won't need accessors like .Tables[0]. It will already be a DataTable and thus more direct to access anyway.
This modification would of course have to be replicated to all of your methods where you're trying to cast the DataSource as a DataSet.
Your datasource is a DataTable, not a DataSet. You cannot cast a DataTable to a DataSet.
DataTable dtUpdateXMLFile = (DataTable)gvPartNumber.DataSource;
dtUpdateXMLFile.Rows[index]["partid"] = partId;
dtUpdateXMLFile.Rows[index]["partnumber"] = partNumber;
dtUpdateXMLFile.WriteXml(Server.MapPath("~/xml/storeUserInfo.xml"));
How to add the checkbox field in gridview programatically, what's wrong with my code?
try
{
string Data_source=#"Data Source=A-63A9D4D7E7834\SECOND;";
string Initial_Catalog=#"Initial Catalog=replicate;";
string User=#"User ID=sa;";
string Password=#"Password=two";
string full_con=Data_source+Initial_Catalog+User+Password;
SqlConnection connection = new SqlConnection(full_con);
connection.Open();
SqlCommand numberofrecords = new SqlCommand("SELECT COUNT(*) FROM dbo.Table_1", connection);
DataSet ds2 = new DataSet();
SqlDataAdapter testadaptor = new SqlDataAdapter();
testadaptor.SelectCommand = new SqlCommand("SELECT COUNT(*) FROM dbo.Table_1", connection);
testadaptor.Fill(ds2);
grid1.DataSource = ds2;
CheckBoxField c = new CheckBoxField();
grid1.Columns.Add(c);
grid1.DataBind();
numberofrecords.Dispose();
connection.Close();
connection.Dispose();
}
catch (Exception a)
{
Response.Write("Please check ");
Response.Write(a.Message.ToString());
Response.Write(a.Source.ToString());
}//catch
The CheckBoxField will probably want a value for the DataField property. This should match the column names or aliases in your query. (I don't think a checkbox will work with number results, though.)
Edited: didn't realize what you were trying to do. A template field and a regular checkbox should get you closer to what you want. Something like this?
e.g.
const int ColumnSelect = 0;
protected void Page_Load(object sender, EventArgs e)
{
//Get real data here.
DataTable dt = new DataTable();
dt.Columns.Add("count");
dt.Rows.Add(dt.NewRow());
dt.Rows[0][0] = "5";
GridView1.Columns.Add(new TemplateField());
BoundField b = new BoundField();
GridView1.Columns.Add(b);
b.DataField = "count";
GridView1.DataSource = dt;
GridView1.DataBind();
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType != DataControlRowType.Header)
{
e.Row.Cells[ColumnSelect].Controls.Add(new CheckBox());
}
}
Edit #2: as for getting the value, you can certainly do this. Are you looking for a Javascript or server-side solution? Here's a simple example for server-side if you had a button click:
protected void Button1_Click(object sender, EventArgs e)
{
foreach(GridViewRow row in GridView1.Rows)
{
//Could also use (CheckBox)row.Cells[ColumnSelect].FindControl if you give the checkboxes IDs when generating them.
CheckBox cb = (CheckBox)row.Cells[ColumnSelect].Controls[0];
if (cb.Checked)
{
//Do something here.
}
}
}
I had to specify which checkbox object, like this
System.Web.UI.WebControls.CheckBox
Also I had to add this to the gridview aspx page
OnRowDataBound="GridView1_RowDataBound"