I'm using the DEVExpress's gridview and have this code that deletes the selected gridview row from another control's customcallback,
the line
GridFrom.DeleteRow(int.Parse(rowKey[2]));
retrieves the correct visibleIndex but does not remove the row from the gridview. The databind also does not refreshes the gridview's data and it requires refreshing of the page for the data to update
protected void ASPxTreeList1_CustomCallback(object sender, DevExpress.Web.ASPxTreeList.TreeListCustomCallbackEventArgs e)
{
string[] rowKey = e.Argument.Split('|');
string strConnectionString = ConfigurationManager.ConnectionStrings["dbname"].ConnectionString;
using (SqlConnection conn = new SqlConnection(strConnectionString))
{
string query = "DELETE FROM Table WHERE id=#id";
using (SqlCommand cmd = new SqlCommand(query, conn))
{
conn.Open();
cmd.Parameters.AddWithValue("#id", rowKey[0]);
cmd.ExecuteNonQuery();
conn.Close();
}
}
GridFrom.DeleteRow(int.Parse(rowKey[2])); //rowKey[2] is the visibleIndex
GridFrom.DataBind();
}
}
it requires refreshing of the page for the data to update
You don't see grid changes, because ONLY ASPxTreeList is updated during ITS OWN callback.
As a possible solution, disable ASPxTreeList's callbacks or delete a grid row using the grid's CustomCallback instead (in a similar manner).
<dx:ASPxTreeList ID="ASPxTreeList1" runat="server" EnableCallbacks="false">
</dx:ASPxTreeList>
Check the The concept of callbacks - Why is it impossible to update external control data during a callback to another control learning guide regarding this.
Related
Using C# and Winform.
I read a couple of similar questions but couldn't find any great answers that could interlock with my code. So, bear with me and thank you in advance for helping me.
I have a single form that contains multiple User Controls. Inside the first user control, you can insert, update and delete records from the database. In the second User Control, there is a datagridview that is populated with all records.
The problem I have is that whenever I insert, update or delete a record inside the first user control. It won't refresh inside the datagridview when I swap to the second user control.
Beneath is the second user control that populates the datagridview
private void populate()
{
database.OpenConnection();
string query = "SELECT id, name, qoute, time, date from maintable";
SQLiteDataAdapter sda = new SQLiteDataAdapter(query, database.connection);
SQLiteCommandBuilder builder = new SQLiteCommandBuilder(sda);
var ds = new DataSet();
sda.Fill(ds);
dtgNav.DataSource = ds.Tables[0];
databas.CloseConnection();
}
private void Navigation_Load(object sender, EventArgs e)
{
populate();
dtgNav.Columns[0].HeaderText = "ID";
}
public void Refresh()
{
this.Refresh();
}
Beneath is the code for adding a record to the datagridview in the first user control
private void btnAdd_Click(object sender, EventArgs e)
{
database.OpenConnection();
string query = "INSERT INTO maintable (`id`, `name`, `qoute`, `time`,`date`) VALUES (#Id, #Name, #Qoute, #Time, #Date)";
SQLiteCommand command = new SQLiteCommand(query, database.connection);
command.Parameters.AddWithValue("#Id", tbxID.Text);
command.Parameters.AddWithValue("#Name", tbxName.Text.Trim());
command.Parameters.AddWithValue("#Qoute", tbxQoute.Text.Trim());
command.Parameters.AddWithValue("#Time", tbxTime.Text.Trim());
command.Parameters.AddWithValue("#Date", dtpDate.Value.ToString("yyyy-MM-dd"));
command.ExecuteNonQuery();
MessageBox.Show("Added new event into the database.");
database.CloseConnection();
usercontrol2.Refresh();
}
I would appreciate it if we found a way to refresh the datagridview when the button is clicked without changing the original code all too much.
You have a public void Refresh method in the second usercontrol, try modifying this.Refresh();, to say populate();. this should call your private void populate method that you called when loading which should reload the grid. Let me know if this helps.
Background information:
I have a SQL connected datalist, one of the columns is called work_order
In the datalist I have inserted a button btn_Start. The button is populated at the end of each set
The goal of the btn_Start is to do a database insert, the insert needs to includes the work_order value from the set of data the button is clicked in (so the insert can be tied to the work_order value.)
btn_Start code:
protected void btn_Start(object sender, EventArgs e)
{
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["nothanks"].ConnectionString))
{
String query = "INSERT INTO [TimeTest] ([Starttime], [Work_Order]) VALUES (#Starttime, #Work_Order)";
using (SqlCommand CCC = new SqlCommand(query, connection))
{
connection.Open();
CCC.CommandType = CommandType.Text;
CCC.Parameters.Add("#Starttime", SqlDbType.DateTime).Value = DateTime.Now;
CCC.Parameters.Add("#Work_Order", SqlDbType.Int).Value = lb_User1.Text.ToString();
CCC.ExecuteNonQuery();
}
}
}
To grab text of the work_order column, I'm using the itemcommand event to propagate a label (lb_User1).
DataList1_ItemCommand` code:
protected void DataList1_ItemCommand(object source, DataListCommandEventArgs e)
{
DataList2.SelectedIndex = e.Item.ItemIndex;
lb_User1.Text = (DataList2.SelectedItem.FindControl("Work_OrderLabel4") as Label).Text;
}
This works well, each time btn_Start is pushed, lb_User1 is updated with the right information.
The issue: when btn_Start is clicked, both btn_Start and DataList1_ItemCommand fire. But DataList1_ItemCommand fires after btn_Start. Which means lb_User1 isn't updated with the right info yet, and as such the insert fails to work as needed.
NOTES:
the lb_User1 isn't needed, I planned to go direct to the SQL insert. lb_User1 was used for code testing (so I can see what's going on)
My objective is to do the SQL insert with the grabbed data from datalist (Work_OrderLabel4). If I can accomplish this objective a better way that would also solve the issue.
btn_Start isn't going to be the only button in the datalist. One possible solution is go way from having two events and only doing things under the itemcommand event, but how do you separate out which button fires, without involving their respective events.
Objective: I'm trying to get each embedded start button to grab its corresponding work_order value for use in a SQL insert. The above is trying to accomplish this task, I'm almost there but I'm having the issue stated above. I'm open for other ways to accomplish this task (see picture of clarification)
Additional Information:
protected void DL_Main_ItemCommand(object source, DataListCommandEventArgs e)
{
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["test"].ConnectionString))
{
String query = "INSERT INTO [TimeTest] ([Starttime], [Work_Order]) VALUES (#Starttime, #Work_Order)";
using (SqlCommand CCC = new SqlCommand(query, connection))
{
connection.Open();
CCC.CommandType = CommandType.Text;
CCC.Parameters.Add("#Starttime", SqlDbType.DateTime).Value = DateTime.Now;
// All you need is the value of Work_OrderLabel4 of the selected item so just do it like this.
CCC.Parameters.Add("#Work_Order", SqlDbType.Int).Value = (DL_Main.SelectedItem.FindControl("Work_OrderLabel") as Label).Text;
CCC.ExecuteNonQuery();
}
}
}
After Running
Get rid of btnStart and put the code below in your DataList1_ItemCommand. The only line I changed is the one with my comment:
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["nothanks"].ConnectionString))
{
String query = "INSERT INTO [TimeTest] ([Starttime], [Work_Order]) VALUES (#Starttime, #Work_Order)";
using (SqlCommand CCC = new SqlCommand(query, connection))
{
connection.Open();
CCC.CommandType = CommandType.Text;
CCC.Parameters.Add("#Starttime", SqlDbType.DateTime).Value = DateTime.Now;
// All you need is the value of Work_OrderLabel4 of the selected item so just do it like this.
CCC.Parameters.Add("#Work_Order", SqlDbType.Int).Value = (DataList2.SelectedItem.FindControl("Work_OrderLabel4") as Label).Text;
}
CCC.ExecuteNonQuery();
}
}
Also, as a side note, please give your controls better names than DataList1. Perhaps DataListTimeTest since it deals with TimeTest table.
I need to update selected row in datagrid when i click on button Ponuda.
The problem is, when i click on button, nothing happens, but when i restart application, whole list is updated. So i need a way to update only the row i have selected and to update it right away and not after application restart.
This is my code for button click :
private void button3_Click(object sender, RoutedEventArgs e)
{
// count = 120;
// tmr.Start();
using (SqlConnection conn = new SqlConnection(#"data source=ZC-PC\SQLEXPRESS;database=Aukcija;integrated security=true;"))
{
DataTable cena1 = new DataTable();
conn.Open();
SqlDataAdapter DA = new SqlDataAdapter(" UPDATE Predmet SET trenutnaCena = trenutnaCena + 1", conn);
SqlCommand cmd = new SqlCommand("UPDATE Predmet SET trenutnaCena = trenutnaCena + 1", conn);
cmd.ExecuteNonQuery();
DA.Update(cena1);
conn.Close();
}
}
If you are using bindings, it SHOULD be updating. The reason it might not be is if whatever object your binding to the DataGrid (which should be an ObservableCollection or class based on one) does not implement INotifyPropertyChanged, the collection will never know a property change occurred.
If you haven't already, implement INotifyPropertyChanged and raise OnPropertyChanged event for each property. Then, when a value changes, it'll reflect both in the DataGrid and the actual collection being bound.
You'll want to make sure you have an event that updates the database with the new collection values whenever such and such happens (which I noticed button3_Click takes care of).
If this doesn't work, let me know, because it should.
When user select any record from the GridView then my DetailView is updated based on the selection of the GridView. So what I am trying to do is that when I delete anything from the DetailView then I want to refresh the GridView so basically I don’t want to show still the deleted record in the GridView. I have tried to resolve this issue by doing the data bind after my connection and SQL statement but it does not refresh it. One thing to note is that I am using a Accordion pane but both my gridview and the detailview are on the same pane. I am not sure if this is breaking anything. Here is my code:
protected void Refresh_ItemCommand(object sender, DetailsViewCommandEventArgs e)
{
if (e.CommandName.Equals("Delete", StringComparison.CurrentCultureIgnoreCase))
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString);
SqlDataAdapter da = new SqlDataAdapter("select ID, Name, Address from dbo.MyTable", con);
DataTable dt = new DataTable();
da.Fill(dt);
Gridview1.DataSource = dt;
Gridview1.DataBind();
}
}
You may use the event of the Data view called "ItemDeleted" as follows:
DetailViewName_ItemDeleted(object sender,
DetailsViewDeletedEventArgs e)
{
// Refresh the GridView control after a new record is updated
// in the DetailsView control.
GridViewName.DataBind();
}
The above code is from the official MSDN site for detail view control.
The other way (which I prefer) is to handle the data grid during the Page_load procedure so when you press your delete button in the detail view, the page will perform a postback.
So in the procedure Page_load you can call another procedure which fills the data grid. The code might be like this:
if (isPostback)
{
FillGrid();
}
private void FillGrid()
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString);
SqlDataAdapter da = new SqlDataAdapter("select ID, Name, Address from dbo.MyTable", con);
DataTable dt = new DataTable();
da.Fill(dt);
Gridview1.DataSource = dt;
Gridview1.DataBind();
}
Your code doesn't show anything where the record is actually deleted so it's understandable that when you re-fetch the data still contains everything.
What you need to do is:
Execute a sql statement to delete the record
Re-fetch the data
Rebind the data.
If you follow those 3 steps it will work.
try to use the event that is called in case of pressing the delete key from the DGV
private void DGV_DeleteKeyPressed(object sender, KeyEventArgs e)
{
//enter code here
}
I am trying to display my data in a gridview.
It works fine, until . . . . .
I want to do paging (20 data per page), it causes an error NotSupportedException was unhandled .
How do i solve this?
This is my code.
I also have set paging to true.
public void bindGV()
{
string strCon = Database.GetConStr();
SqlConnection sqlCon = new SqlConnection(strCon);
SqlCommand sqlCommand = new SqlCommand("select * from Account", sqlCon);
sqlCon.Open();
SqlDataReader reader = sqlCommand.ExecuteReader();
StaffGV.DataSource = reader;
StaffGV.DataBind();
}
protected void GV_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GV.PageIndex = e.NewPageIndex;
bindGV();
}
The error comes from the GV_PageIndex.
Please remove the code from the PageIndexChanging event & see what happens.
Read your code again & it implies that - on every click of the next page, you would want to fetch the data from the database and bind it to the datagrid. This must not be done.
You don't need to do anything explicit to handle paging in datagrid, except to set a few properties. Read some intro tutorials on how to handle paging in datagrid.