I am creating login application (Windows Forms) in C# and using .NET Framework 4.5 with Visual Studio 2012.
I have already entered username and password into database manually.
So in LoginForm, where user enter their username and password my code is like:
public partial class LoginForm : Form
{
public LoginForm()
{
InitializeComponent();
}
System.Data.SqlServerCe.SqlCeConnection con;
System.Data.SqlServerCe.SqlCeDataAdapter da;
DataSet ds1;
int MaxRows = 0;
int inc = 0;
private void go_Click(object sender, EventArgs e)
{
DataRow dRow = ds1.Tables["Users"].Rows[inc];
if (EnterMasterPassword.Text == dRow.ItemArray.GetValue(1).ToString())
{
this.DialogResult = DialogResult.OK;
this.Close();
}
else
MessageBox.Show("Try again");
}
private void LoginForm_Load(object sender, EventArgs e)
{
con = new System.Data.SqlServerCe.SqlCeConnection();
con.ConnectionString = "Data Source=C:\\PMDatabase.sdf";
con.Open();
ds1 = new DataSet();
string sql = "SELECT * From tbl_login";
da = new System.Data.SqlServerCe.SqlCeDataAdapter(sql, con);
da.Fill(ds1, "Users");
MaxRows = ds1.Tables["Users"].Rows.Count;
con.Close();
}
}
*where go is an button*
This works perfectly and users login successfully. But I have no idea how to provide an update/change password functionality to user using Windows Forms. How to update database? And username and password field in it?
So far I have done following procedure:
When user clicks on "Update Password" button a new form (name: Form7) opens which has 3 labels, 3 text-boxes and one button- namely:-
TextBox1--> CurrentPassword
TextBox2--> NewPassword
TextBox3--> ConfirmNewPassword
Button--> UpdateUsrPassword
the code for Form7 is like:-
public partial class Form7 : Form
{
public PasswordsAndData()
{
InitializeComponent();
}
System.Data.SqlServerCe.SqlCeConnection con1;
System.Data.SqlServerCe.SqlCeDataAdapter da1;
DataSet ds2;
int totalPasswords = 0, inc = 0;
private void Form7_Load(object sender, EventArgs e)
{
con1 = new System.Data.SqlServerCe.SqlCeConnection();
con1.ConnectionString = "Data Source=C:\\PMDatabase.sdf";
con1.Open();
ds2 = new DataSet();
string sql = "SELECT * From tbl_UserData";
da1 = new System.Data.SqlServerCe.SqlCeDataAdapter(sql, con1);
da1.Fill(ds2, "UserData");
totalPasswords = ds2.Tables["UserData"].Rows.Count;
con1.Close();
}
private void UpdateUsrPassword_Click(object sender, EventArgs e)
{
if(NewPassword.Text == ConfirmNewPassword.Text)
{
DataRow dRow1 = ds2.Tables["UserData"].NewRow();
dRow1[1] = ConfirmNewPassword.Text;
ds2.Tables["UserData"].Rows.Add(dRow1);
UpdateDB();
MessageBox.Show("Password Updated");
totalPasswords++;
inc = totalPasswords - 1;
}
}
private void UpdateDB()
{
System.Data.SqlServerCe.SqlCeCommandBuilder cb1;
cb1 = new System.Data.SqlServerCe.SqlCeCommandBuilder(da1);
cb1.DataAdapter.Update(ds2.Tables["UserData"]);
}
}
But the above code is not updating the password. How to correct above code? So its works perfectly.
Please guide me.
DataRow dRow1 = ds2.Tables["UserData"].NewRow();
dRow1[1] = ConfirmNewPassword.Text;
ds2.Tables["UserData"].Rows.Add(dRow1);
UpdateDB();
You are adding a row in your UpdateUsrPassword_Click but shouldn't you instead updating the existing row?
You should do:
Get actual password from db
UPDATE of the existing row containing the actual password
instead of adding a row you should use something like this:
dataSet1.Tables["Customers"].Rows[4]["CompanyName"] = "Updated Company Name";
this updates the value in the dataset, which you can then push back to the database.
source with more info on editing values in a dataset:
https://msdn.microsoft.com/en-us/library/tat996zc.aspx
Related
Datagridview = DataGridMain
Form1 = MainPage
Form2 = ExpensesForm
What I'm trying to do is simply, update the datagrid (DataGridMain) on MainPage when the Confirm button is clicked. I apologize if this has been answered before but after trying every solution that has been posted, I could not get it to work. The Datagrid updates when I close and reopen the application but it doesn't when the Confirm button on ExpensesForm is clicked. This is what I've got so far:
MainPage:
public void LoadDatabase()
{
SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM datagrid", "server = DESKTOP-8QADBBH; database = test; UID = test; password = test");
DataSet ds = new DataSet();
da.Fill(ds, "datagrid");
DataGridMain.DataSource = ds.Tables["datagrid"].DefaultView;
}
private void MainPage_Load(object sender, EventArgs e)
{
LoadDatabase();
}
ExpensesForm:
MainPage mainPage = new MainPage();
private void ButtonConfirmExpenses_Click(object sender, EventArgs e)
{
bool success = double.TryParse(TextBoxExpensesPrice1.Text, out double userInput);
string mainconn = ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString;
SqlConnection sqlconn = new SqlConnection(mainconn);
string sqlquery = "insert into [dbo].[DATAGRID] (CATEGORY, TRANSACTIONS) values (#CATEGORY, #TRANSACTIONS)";
SqlCommand sqlcomm = new SqlCommand(sqlquery, sqlconn);
sqlconn.Open();
if (success)
{
if (ComboBoxExpensesCategory1.SelectedItem == null)
{
System.Windows.Forms.MessageBox.Show("Invalid Input. Please choose a category.");
}
else
{
sqlcomm.Parameters.AddWithValue("#TRANSACTIONS", TextBoxExpensesPrice1.Text.ToString());
sqlcomm.Parameters.AddWithValue("#CATEGORY", ComboBoxExpensesCategory1.Text.ToString());
sqlcomm.ExecuteNonQuery();
SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM datagrid", "server = DESKTOP-8QADBBH; database = test; UID = test; password = test");
DataSet ds = new DataSet();
da.Fill(ds, "datagrid");
mainPage.DataGridMain.DataSource = ds.Tables["datagrid"].DefaultView;
sqlconn.Close();
this.Close();
mainPage.LoadDatabase();
mainPage.DataGridMain.Update();
mainPage.DataGridMain.Refresh();
}
}
else
{
System.Windows.Forms.MessageBox.Show("Invalid Input. Please insert a number.");
}
}
I am trying to make it so that when changing the value in the comboBox, the database is displayed in the dataGridview. Everything seems to work, but when you close the form it gives an error:
enter image:
Code:
namespace Cursach
{
public partial class VoucherForm : Form
{
public VoucherForm()
{
InitializeComponent();
}
public void VoucherCountry()
{
dataGridView1.AllowUserToAddRows = false;
dataGridView1.AllowUserToDeleteRows = false;
dataGridView1.AllowUserToOrderColumns = false;
dataGridView1.AllowUserToResizeRows = false;
dataGridView1.AllowDrop = false;
dataGridView1.ReadOnly = true;
DB dB = new DB();
SqlCommand command = new SqlCommand("SELECT * FROM Voucher WHERE Name_Country= #nC", dB.ConnectionSQL());
command.Parameters.Add("#nC", SqlDbType.VarChar).Value = comboBox1.SelectedValue;
DataTable table = new DataTable();
SqlDataAdapter adapter = new SqlDataAdapter();
dB.OpenSQL();
adapter.SelectCommand = command;
adapter.Fill(table);
dataGridView1.DataSource = table;
dB.ClodeSQL();
}
private void VoucherForm_Load(object sender, EventArgs e)
{
this.countryTableAdapter.Fill(this.cursacDat.Country);
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
VoucherCountry();
}
}
You have a DB class which is good to separate you database code from your user interface code. I moved the database code to retrieve the Country data to the DB class. Notice how the DB class knows nothing about the user interface and the user interface knows nothing about the database.
Database objects need to be closed and disposed. using blocks take care of this for you even if there is an error.
public class DB
{
private string ConStr = "Your connection string";
public DataTable GetCountryData(string nC)
{
DataTable dt = new DataTable();
using (SqlConnection cn = new SqlConnection(ConStr))
using (SqlCommand cmd = new SqlCommand("SELECT * FROM Voucher WHERE Name_Country= #nC", cn))
{
cmd.Parameters.Add("#nC", SqlDbType.VarChar, 100).Value = nC;
cn.Open();
dt.Load(cmd.ExecuteReader());
}
return dt;
}
}
Then in the form.
private void OpCode()
{
if (comboBox1.SelectedIndex < 0)
{
MessageBox.Show("Please select a value in the drop down.");
return;
}
DB DataClass = new DB();
dataGridView1.DataSource = DataClass.GetCountryData(comboBox1.SelectedValue.ToString());
}
I'm fairly new to C# and coding in general. I've looked through similar questions and didn't have much luck fixing this.
I am making an app that stores Student details for attendance in tables, in a database. Currently when I run it, the details are added to the tables from textboxes. A button opens a separate form with a datagridview, but the details are not updated in this. If I rerun the application and open the second form, the datagridview has been updated. How do I get the datagridview to update based on information added to the table while the application is running?
This is the code that adds the details to the table
using (SqlConnection sc = new SqlConnection())
{
sc.ConnectionString = #"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\corry\Desktop\StudentAttendanceBurton\Attendance.mdf;Integrated Security=True";
sc.Open();
using (SqlCommand com = sc.CreateCommand())
{
com.CommandText =
"insert into BUS102(\n" +
" Name,\n" +
" [Student ID],\n" +
" Date)\n" +
"values(\n" +
" #prm_Name,\n" +
" #prm_Student_ID,\n" +
" #prm_Date)";
com.Parameters.Add("#prm_Name", SqlDbType.NVarChar, 50).Value = student.Name;
com.Parameters.Add("#prm_Student_ID", SqlDbType.Int).Value = student.StudentID;
com.Parameters.Add("#prm_Date", SqlDbType.SmallDateTime).Value = student.Date;
com.ExecuteNonQuery();
}
}
This is the code for the form that has the datagridview
public partial class AttendanceForm : Form
{
public AttendanceForm()
{
InitializeComponent();
}
private void bUS102BindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
this.Validate();
this.bUS102BindingSource.EndEdit();
this.tableAdapterManager.UpdateAll(this.attendanceDataSet);
}
private void AttendanceForm_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'attendanceDataSet.BUS102' table. You can move, or remove it, as needed.
this.bUS102TableAdapter.Fill(this.attendanceDataSet.BUS102);
}
}
public partial class Form1 : Form {
private DataSet m_ds = new DataSet();
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
using (SqlConnection conn = new SqlConnection(#"Data Source=YOURSql;Initial Catalog=YOURDB;Integrated Security=True")) {
// set command
SqlCommand cmd = new SqlCommand("SELECT * FROM YourTable", conn);
SqlDataAdapter da = new SqlDataAdapter(cmd);
conn.Open();
da.Fill(m_ds);
// bind data to dataGrid
dataGridView1.DataSource = m_ds.Tables[0];
// refresh Data
dataGridView1.Refresh();
conn.Close();
}
}
private void cmdChangeData_Click(object sender, EventArgs e) {
// add new row explicit
DataRow nr = m_ds.Tables[0].NewRow();
nr[0] = "0000";
nr[1] = "xxxx";
// add new row to DataSet (just in memory, NOT TO DB)
m_ds.Tables[0].Rows.Add(nr);
// Refresh Data
dataGridView1.Refresh();
}
}
You have to refresh datagridview
this.dataGridView1.Refresh();
So I'm trying to create sort of an overview utility of sites, with different infos on each site.
I'd like to have a dropdown list / combobox, reading a sqldb and create items according to the db. Then I would like different textboxes to get populated with a value from a column.
Say my db table is called "AvSites" so far (just for the sake of it) i have "projectNr", "siteName", "siteClients" and "siteLicenses" columns I'd like each of these to populate some textbox / label somewhere.
I've tried the following, which kinda works, Ive had the code working most of the time, but the thing that defeats me is having the data change with the combobox item selected.
I hope you can help, and so here is my code so far (I have a login window, before this "main" program starts, just so you're not wondering)
And I'm quite new to C# so if there's something thats done inefficient thats the reason :) Im still learning.
namespace AvOverview{
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
}
private void Button1_Click(object sender, EventArgs e)
{
//btn_LogOut Click Event
this.Hide();
Form1 fl = new Form1();
fl.Show();
}
private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
{
Application.Exit();
}
private void FrmMain_Load(object sender, EventArgs e)
{
string cs = #"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Database1.mdf";
SqlConnection con = new SqlConnection(cs);
con.Open();
string strCmd = "select * from AvSites";
SqlCommand cmd = new SqlCommand(strCmd, con);
SqlDataAdapter da = new SqlDataAdapter(strCmd, con);
DataSet ds = new DataSet();
da.Fill(ds);
combo1.ValueMember = "id";
combo1.DisplayMember = "siteName";
combo1.DataSource = ds.Tables[0];
combo1.Enabled = true;
this.combo1.SelectedIndex = -1;
cmd.ExecuteNonQuery();
con.Close();
}
private void Combo1_SelectedIndexChanged(object sender, EventArgs e)
{
string cs = #"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Database1.mdf";
string strCmd = "select id from AvSites";
SqlConnection con = new SqlConnection(cs);
SqlCommand cmd = new SqlCommand(strCmd, con);
con.Open();
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{//this last part is solely for testing if the text changed the way I wanted.
label1.Text = dr.GetValue(1).ToString();
label2.Text = dr.GetValue(2).ToString();
label3.Text = dr.GetValue(0).ToString();
label4.Text = dr.GetValue(3).ToString();
You don't need to call the database again. All the info are in the current selected item.
When you set the DataSource of your combo to a datatable like you do in the click event each element of the combo is a DataRowView and from this element you can get all the info extracted from the database from your initial query
private void Combo1_SelectedIndexChanged(object sender, EventArgs e)
{
DataRowView rv = Combo1.SelectedItem as DataRowView;
if(rv != null)
{
label1.Text = rv[1].ToString();
label2.Text = rv[2].ToString();
label3.Text = rv[0].ToString();
label4.Text = rv[3].ToString();
}
}
Side note: There are some improvements needed in your code.
First you should store the connection string in the config file and read it back with the ConfigurationManager class. Read about Configuration in NET
Second you shouldn't work with disposable objects like you do now. A disposable object should be disposed as soon as you have finished to use it. In particular the SqlConnection keeps valuable system resources both on your machine and on the server. You should start to use the using statement
string strCmd = "select * from AvSites";
using(SqlConnection con = new SqlConnection(.......))
using(SqlCommand cmd = new SqlCommand(strCmd, con)))
{
con.Open();
SqlDataAdapter da = new SqlDataAdapter(strCmd, con);
DataSet ds = new DataSet();
da.Fill(ds);
combo1.ValueMember = "id";
combo1.DisplayMember = "siteName";
combo1.DataSource = ds.Tables[0];
combo1.Enabled = true;
this.combo1.SelectedIndex = -1;
// ??? not needed ==> cmd.ExecuteNonQuery();
// not needed with using ==> con.Close();
}
// Here the connection is closed and disposed and resources are released
I'm working on a Windows Forms project that requires me to connect to an access database and navigate through records, and add/delete them. I've looked at a few tutorials online, and thought I followed them correctly. Anyway, I can add a new item and it will show up fine in the window, but after I exit, all changes are lost and the database isn't saved at all.
Any advice would be appreciated. Following is the code I'm using to save the database upon button-press. I've also hard-coded in some test values just for testing purposes.
private DataSet data;
private int inc;
private int MaxRows;
private OleDbConnection connect;
private OleDbDataAdapter da;
/**
* Autoloads the first item into our form's text fields.
*/
private void BookMgmt_Load(object sender, EventArgs e)
{
data = new DataSet();
connect = new System.Data.OleDb.OleDbConnection();
connect.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=.\\LibraryAppDB.accdb";
string Books = "SELECT * FROM Books";
da = new OleDbDataAdapter(Books, connect);
connect.Open();
da.Fill(data, "Books");
Navigate();
MaxRows = data.Tables["Books"].Rows.Count;
connect.Close();
connect.Dispose();
}
/**
*changes data within the array update form with current
*item's info
*/
private void Navigate()
{
ID = data.Tables["Books"].Rows[inc];
textBox1.Text = ID.ItemArray.GetValue(0).ToString();
textBox2.Text = ID.ItemArray.GetValue(1).ToString();
textBox3.Text = ID.ItemArray.GetValue(2).ToString();
textBox5.Text = ID.ItemArray.GetValue(3).ToString();
textBox6.Text = ID.ItemArray.GetValue(4).ToString();
textBox7.Text = ID.ItemArray.GetValue(7).ToString();
textBox8.Text = ID.ItemArray.GetValue(8).ToString();
textBox10.Text = ID.ItemArray.GetValue(5).ToString();
textBox11.Text = ID.ItemArray.GetValue(6).ToString();
}
/**
* Saves the new element added into our actual database
*/
private void saveButton_Click(object sender, EventArgs e)
{
OleDbCommandBuilder cb;
DataRow dRow = data.Tables["Books"].NewRow();
cb = new OleDbCommandBuilder(da);
dRow[0] = 11;
dRow[1] = "test";
dRow[2] = "test";
dRow[3] = "test";
dRow[5] = "test";
dRow[6] = "test";
dRow[7] = "test";
dRow[8] = "test";
data.Tables["Books"].Rows.Add(dRow);
data.AcceptChanges();
da.Update(data, "Books");
MaxRows = MaxRows + 1;
inc = MaxRows - 1;
Navigate();
MessageBox.Show("Entry Added", "Success!", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
/**
* Deletes the current item displayed on the form
*/
private void deleteButton_Click(object sender, EventArgs e)
{
OleDbCommandBuilder cb;
cb = new OleDbCommandBuilder(da);
if (textBox1.Text == "1")
{
}
else
{
data.Tables["Books"].Rows[inc].Delete();
this.MaxRows--;
this.inc = 0;
Navigate();
data.AcceptChanges()
da.Update(data, "Books");
MessageBox.Show("Gone");
}
data.AcceptChanges() resets the RowState on modified and new records to unchanged and removes the deleted records from the dataset. By calling it before the update you're effectively telling the DataAdapter "nothing to do here"
Just move the calls to accept changes to after the calls to update. The call is important because that way subsequent calls to update w.on't attempt to make the changes again