Populating GridView, dynamically templating the edit fields, saving to database - c#

Alright, I am going to try and be as thorough as possible. I have gone through several (many) tutorials before resorting to posting here if anyone is wondering /=
I have several tables - one contains text/stored-procedure-name pairs which will populate a dropdown menu on the front end (Web Form). The other tables are accessed via the stored procedures. The idea is that I want to be able to be able to control from the back-end which fields are viewable/editable to the user on the front end. I also would like to be able to add / remove stored-procedures to retrieve data without having to mess with the front end.
The user can select from the drop down, and based on the selection a stored-procedure will be executed and then populate the gridview. No problems so far.
Now, ideally, the user will be able to edit the data presented in the gridview. This is easy enough, until we start getting fancy (i.e. overriding the default textbox controls that get generated). For example, when the user presses "edit" in the GridView row, and a record has the datatype "DateTime", I want some sort of calendar/clock to pop up and allow the user to pick the date and time, and then update it back into the database.
I've been running into roadblocks at this point. I've followed the tutorial on dynamically generating editable gridviews (http://aspalliance.com/1125_Dynamically_Templated_GridView_with_Edit_Delete_and_Insert_Options.1), but it does not work with what I am trying to do.
Any help is greatly appreciated, and I hope I have explained this with enough depth!
Code:
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
this.setData();
}
public void setData()
{
//Establishing the SQL Connection
using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["myConnString"].ConnectionString
))
{
//string query;
SqlCommand SqlCommand;
SqlDataReader reader;
SqlDataAdapter adapter = new SqlDataAdapter();
//Open the connection to db
conn.Open();
//Generating the query to fetch the contact details
//query = "SELECT * FROM " + DropDownList1.SelectedValue + ";";
SqlCommand = new SqlCommand(DropDownList1.SelectedValue, conn);
//execute the query
reader = SqlCommand.ExecuteReader();
//Assign the results
GridView1.DataSource = reader;
//Bind the data
GridView1.DataBind();
conn.Close();
} }
The issue is that when this gets triggered:
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
GridView1.EditIndex = e.NewEditIndex;
this.setData();
}
All of the editable fields default to text boxes. I have been unable to get them to format according to datatype. Again, as an example, if the datatype is DateTime, a calendar should pop up and let user select date/time.
I know that there is a way to do it using except this is for statically generated gridviews. This gridview is dynamic and its contents depend on procedures executed from the backend, so I can't hardcode the edit formats into the front end.

Related

Button not updating the database

I want to give the users to the ability to update their info on database. I made the button to for the software to take the name from one of the textboxes and send it to the database.
public void Updatebtn_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection("Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=\"C:\\Users\\Ray-a\\Downloads\\New folder (2)\\Blood Donation\\Blood Donation\\App_Data\\BloodDonationDB.mdf\";Integrated Security=True");
con.Open();
SqlCommand cmd = new SqlCommand("Update Users set First_Name=#fn WHERE ID = '2' ", con);
cmd.Parameters.AddWithValue("#fn", UFirstName.Text);
cmd.ExecuteNonQuery();
con.Close();
}
I watched a YouTube video and followed step by step. But it didn't work.
The button works and executes command. But something is wrong with either sql command or connection because the database doesn't get updated
because your codes seems okey to me with no problems in it i'll give you some tips that will make sure you almost avoiding most mistakes biggeners like me did which caused unexplaind errors.
these tips will REALLY REALLY help you in your programming journey.
when adding a new local database, create a newfolder and name it DataBaseFolder as an example inside your project folder , so you always know where is your database and you dont get confused about other databases in the default location VS saves them, and its better that the project folder is placed in the partition "C" in a default folder of windows.
when creating a new table, name it probably in the definition part at the bottom where you can see:
create table [dbo].[TableName] then press Ctrl + s, make sure to save that table in the same folder as your database, so you always know this table is for this project.
)))) each time you update your table definition like column name or type, or adding a new column or deleting an existing one, make sure to press Ctrl +s and save the table (replace) in the same folder you originally created it, that will make sure you don't get the error most new developers like me were stuck at which is the update window is taking forever to preview the changes.
))))) to make it easy for myself to use the sql commands, i created a script (class.cs) and put the important codes in methods with parameters so i save a lot of time when i was restarting over my program because of some mistakes i did :D
first i defined my sql connection in the class named SqlCodes:
SqlConnection con = new SqlConnection("Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=\"C:\\Users\\Ray-a\\Downloads\\New folder (2)\\Blood Donation\\Blood Donation\\App_Data\\BloodDonationDB.mdf\";Integrated Security=True");
then i created my methods, examples:
public void QueryCommand(string QueryString)
{
con.Open();
SqlCommand cmd = new SqlCommand(QueryString, con);
cmd.ExecuteNonQuery();
con.Close();
}
public void FillingDataGridView(parameter1,parameter2, parameter3)
{
con.Open();
some code;
con.Close();
}
So, back to my main class where my button will function:
SqlCodes sqlCodes = new SqlCodes();
in the button i now can write:
sqlCodes.QueryCommand("insert into MyTable values (your values)");
or
sqlCodes.RefreshDataGridViewAfterEntry (parameter1,parameter2,parameter3)
or
string queryCommand = " insert into MyTable values (your values)";
sqlCodes.QueryCommand(queryCommand);
or in the load form method so when you open the program it shows the data you want instantly
{
sqlCodes.FillingDataGridview(parameter1,parameter2,parameter3)
}
if you're having errors with your database, don't delete the files you will find in the solution explorer because it will cause you some errors i couldn't figure their solution, just delete the database in the server explorer, and don't forget to change the sql connection path in the SqlCodes Class you created.
that will save you time and and to avoid errors and make your code very simple, instead of copy paste/ writing about 7 or 8 lines each time you want to do something with your database.
I managed to solve the problem.
As it Turns out. clicking the button also calls page_load. Which has a code that replaces text in the textbox. So the button would first call page_load. Retrieving data from the databox. Then it would put in the textbox.
Then it would take data from the same textbox again and send back it to the database.
I managed to fix it by putting the code in pageload inside in if statement. And then i put !Page.IsPostBack condition inside the if statement.
protected void Page_Load(object sender, EventArgs e)
{
if (Session["Active"] != null && Session["Active"].ToString()
=="Yes" && !Page.IsPostBack)
{
GetUserData();
}
}
Hope that helps.

Get specific column of specific user in datatable

I have a data table, in the data table, I have 3 columns: USERNAME, PASSWORD, and Money.
I want to make a specific setting in my program to make a label the amount of money the user has, and for each user, it will show something else depending on who is logged on at the moment, is it possible and if yes how can I do it?
Thanks in advance.
You can put the amount of money in your label by writing some code. This is used for MSSQL Database connections(in your case).
Here is an example:
using System.Data.SqlClient;//Add this in the using statements at the top of your code.
using (SqlConnection conn = new SqlConnection(#"Data Source = (LocalDB)\MSSQLLocalDB; AttachDbFilename =" +Application.StartupPath+ #"\Database1.mdf; Integrated Security = True"))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = conn;
cmd.CommandText = "SELECT Money FROM Users WHERE Username = #username";
cmd.Parameters.AddWithValue("#username", "User1");
var reader = cmd.ExecuteReader();
reader.Read();
label1.Text = reader.GetValue(0).ToString(); //reader returns an object, you have to convert it in your type.
//GetValue(selected column number)
}
conn.Close();//This line is optional. The connection closes automatically when the using() statement ends.
}
You can add this code in your Form Load event.(If you are working with Win Forms).
The second method is to use Dataset with binding the label to it. This is also powerful and you do not need to know too much sql or how to code, it is more complicated at the beginning but it`s easier and saves time. You can apply it to any of your form elements(buttons, datagridviews,combobox,textbox,etc).
First, go to your label properties and find "DataBindings". Click on advanced. Just click next until you see the connect to database option. If your are connected already with visual studio to your database it will appear in that combobox, otherwise click new connection(I suppose you worked in service based database).Click next and finish. After you have to bind the label to the database(it will create a generated code in your Form Load Event). If you have only one record(one user) in the table it will show only one value, but if you want to show a specific user, you can change that "Fill" generated method in your Form Load Event in other(filtered one with WHERE SQL Clause). You can change that fill method in the Dataset Added in the bottom of your designer of the form. Click on that little arrow near it and choose "edit in designer" option. Click on the table adapter section and right click on his function(in this case Fill() method) and click configure. Here you can change the sql statement and put a WHERE clause in the end.(ex Where Username = ?) The "?" means some variable. After pass in the function created in the form load event your user`s username next to that dataset thing. Done. If you want to work with Win Forms and sql databases I advise you to learn how to use The Datasets, Bindings and TableAdapters. Hope it helps.
Screenshots of my explanations:
!!!! [UPDATE] !!!!
Here is my example program on google drive: Link.
On the right side you can open my service based database(in the project files(Database1)).I'll attach some useful screenshots for creating addition functions in a dataset's table adaper. Also, you have the second method commented in the Form1 load event.

Force Update from a filtered DataGridView to Database

I have created an application to fix a date conversion problem when transferring data from the machines. The conversion works great. I create a DataGridView that contains all records. I then sort the DataGridView to display the data that needs updating using SqlDataAdapter and DataSet. I then make the changes to the data in the DataGridView and click a save button to apply changes to the database table.
try
{
MessageBox.Show("Complete");
this.log5DataGridView.EndEdit();
//this.log5BindingSource.DataSource = this.log5DataGridView.DataSource; <-- Last Resort
this.log5BindingSource.ResetBindings(false);
this.log5BindingSource.EndEdit();
this.log5TableAdapter.Update(roboticlineDataSet.Log5);
}
catch { }
When I run in debug mode the log5DataGridView.DataSource Table[] shows the data changes are available. But the log5BindingSource never seems to get the changes to push it through to the TableAdapter Update. I tried the ResetBindings, EndEdit() the last thing is to take the Datasource and force it to the BindingSource.
If I use the following code to search for the precise record the save / update to database will not occur.
using (SqlDataAdapter adpt = new SqlDataAdapter("SELECT * FROM [dbo].[RoboticLine] WHERE [FSItemNumber] = '" + Value + "' ORDER BY [FSItemNumber] ASC;", conn))
{
DataSet ds = new DataSet();
adpt.Fill(ds);
valueComboBox.Enabled = false;
log5DataGridView.DataSource = ds.Tables[0];
log5DataGridView.Refresh();
this.log5DataGridView.Rows[0].Selected = true;
}//end of adpt using
The Question is if there is a way to save the searched log5DataGridView record back to the database as the datagridview table retains the change but the log5BindingSource still contains the original
this.log5TableAdapter.Fill(this.roboticlineDataSet.Log5);
Thank you.
Found out what was occurring, when I programmed the datagridview to show the searched data it did not change the bindingsource but left it the same from the Form Load ().
this.log5TableAdapter.Fill(this.roboticlineDataSet.Log5);
To resolve this I found the RoboticLineTable in the Dataset.xsd location in the Soultion Explorer. Here I selected the roboticlinetableadapter and right-clicked where i selected Add->Query. Here I created a SQL query with a where ID = #Value to do the required filtering / search. This replaces the using SqlDataAdapter code with this code
this.log5DataGridView.EndEdit();
this.log5BindingSource.EndEdit();
this.log5tableAdapter.FillByID(this.roboticline.Log5, Value);
this.invalidate();
this.log5DatagridView.Refresh();
Now when I wish to save, the BindingSource has the changes made in the datagridview and update / save to the Database. Creating and refilling the tableadapter helps keep the link to the bindingsource for you.
Hope this helps someone else that may run into this in the future

Update Database from changes made in a DataGridView

I attached the DataBase DataSet to a DataGridView to automatically display its content
But now i need to collect the changes made in this DGV to update my database
How can i do that?
You can use a SqlCommandBuilder to create and execute an Update command:
private void UpdateDatabase()
{
//Create an adapter to get the schema and point to the correct table
//Can do something like SELECT * from table_name where 0 = 1
SqlDataAdapter adapt = new SqlDataAdapter(yourSelectString, yourConnectionString);
SqlCommandBuilder builder = new SqlCommandBuilder(adapt);
try
{
adapt.Update(ds.Tables[0]);
ds.Tables[0].AcceptChanges();
}
catch (Exception ex)
{
//Handle any exception here
}
}
This dynamically creates an Update command based on any changes in your DataTable.
Edit
The Code you provided (and removed for some reason), was correctly binding the DataSet to your DataGridView. When you make changes to the values in the cells of the DataGridView it automatically changes the underlying DataTable (in your case ds.Tables[0]. In order to send the changes back to the Database, using the method above will automatically create and execute a SQL Update command sending the changes back to the Database.

Save data to database then load data to Listbox

I have 2 buttons that add to a CheckListBox. The first button adds a Delivery with the customer name, address and arrival Time.
The second button adds a pickup with Delivery Name and Delivery address
I also have a database table called customers with the following columns:
ID, Description, Customer Name, Customer Address, Arrival Time, Delivery Name, Deliver Address
I have about 10 records stored in the database at the moment
My question - how do I code it so that when my program starts it loads the records stored in my database into the CheckListBox and when I add a new delivery or a new pick up it saves it in the Customer table in my database? Also, if I edit or delete within the CheckListBox I want it to update my database table accordingly.
From the looks of the video, you're using SQL Server. You'll need to do a few things in order to get your program where you want it. I'll try my best to get you there, with the information provided (this assumes you are learning and will keep things basic):
"How do I code it so that when my program starts it loads the records stored in my database into the CheckListBox"
You'll need to add this using statement at the top of your windows form class:
using System.Data.SqlClient;
Then, in the form_Load event, connect to your database and retrieve the rows from the customer table (not tested):
private void Form1_Load(object sender, EventArgs e)
{
//Setup connection to your database.
SqlConnection myConnection = new SqlConnection("user id=sql_userID;" +
"password=password;server=server_url;" +
"Trusted_Connection=yes;" +
"database=databaseName; " +
"connection timeout=30");
//Open connection.
myConnection.Open();
//Create dataset to store information.
DataSet ds = new DataSet();
//Create command object and adapter to retrieve information.
SqlCommand myCommand = new SqlCommand("SELECT * FROM Customers", myConnection);
SqlDataAdapter adapter = new SqlDataAdapter(myCommand);
adapter.Fill(ds);
//Loop through each row and display whichever column you wish to show in the CheckListBox.
foreach (DataRow row in ds.Tables)
checkedListBox1.Items.Add(row["ColumnNameToShow"]);
}
The rest of your question is a bit vague because you don't explain how you are going to save a "new" record (with a button, what data is required, what data is the user actually inputting, input types, etc.) or how you are "deleting" a record. This should get you on the right path though and help get you started.

Categories

Resources