I have started to code in C# winforms . One problem I'm finding is learning about subroutines. In visual basic it was really easy but I'm not sure how it works in C# with public and static and void. If when a user presses a button I want to pull up a subroutine from a class would I have the subroutine as static void or public? Also would you use public or static for variables in a class that would be used throughout multiple forms?
An example is this:
private void button1_Click(object sender, EventArgs e)
{
using (OleDbConnection connection = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\RAV21001310\\OneDrive\\Database1.accdb;"))
{
connection.Open();
using (OleDbCommand command = new OleDbCommand("SELECT * FROM tblUser WHERE Username=#Username AND Password=#Password", connection))
{
command.Parameters.AddWithValue("#Username", username.Text);
command.Parameters.AddWithValue("#Password", password.Text);
using (OleDbDataReader reader = command.ExecuteReader())
{
int count = 0;
while (reader.Read())
{
count = count + 1;
}
if (count == 1)
{
MessageBox.Show("Username and password is correct");
}
if (count > 1)
{
MessageBox.Show("Duplicate username and password");
}
if (count == 0)
{
MessageBox.Show("Username or password incorrect");
}
}
}
connection.Close();
}
}
}
public class User
{
public string Username;
public string Password;
public string FirstName;
public string LastName;
public string Gender;
public int Age;
public int TotalPoints;
}
The first block of code is a login form. If I wanted to call it UserLogin() and put it in the user class would I use static or public for it or would I just rename the private void for button click and put that in the user class instead.
Related
I'm learning database connectivity using C# Windows Form Application in Visual Studio and SQL Server Management Studio.
The problem I'm having is I'm unable to access the AddParams() and sqlQueryCmd() functions from the SQLConn.cs Class.
I've tried changing the access modifiers from private to public but it didn't work. Can anyone guide me here? I don't know what I'm doing wrong.
SQLConn.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using Microsoft.Data.SqlClient;
namespace dbConnectivityTest1
{
public class SQLConn
{
public static void Main1(string[] args)
{
using (SqlConnection connString = new SqlConnection("Server=ServerName;Database=DatabaseName;User Id=UserID;\r\nPassword=Password;"))
{
List<SqlParameter> paramList = new List<SqlParameter>();
string AddParams(string tableName, object insVal)
{
SqlParameter sqlparams = new SqlParameter(tableName, insVal);
paramList.Add(sqlparams);
}
SqlCommand sqlCmd = new SqlCommand();
string sqlQueryCmd(string sqlQuery)
{
int recordCount = 0;
string excptnShow = "";
try
{
connString.Open();
SqlCommand sqlCmd = new SqlCommand(sqlQuery, connString);
paramList.ForEach(p => { sqlCmd.Parameters.Add(p); });
paramList.Clear();
DataTable sqlDT = new DataTable();
SqlDataAdapter sqlDA = new SqlDataAdapter(sqlCmd);
recordCount = sqlDA.Fill(sqlDT);
}
catch(Exception ex)
{
excptnShow = "Error: \r\n" + ex.Message;
}
finally
{
if (connString.State == ConnectionState.Open)
{
connString.Close();
}
}
}
}
}
}
}
Form1.cs
namespace dbConnectivityTest1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private SQLConn sqlDB = new SQLConn();
private void enterNametextBox_Click(object sender, EventArgs e)
{
enterNametextBox.Clear();
}
private void submitButton_Click(object sender, EventArgs e)
{
while(fullNameTextBox.Text.Length <= 0)
{
MessageBox.Show("Please enter your Full Name!", "Caption", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation);
}
while(contactTextBox.Text.Length <= 0)
{
MessageBox.Show("Please enter your Contact Number!", "Caption", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation);
}
while(ageTextBox.Text.Length <= 0)
{
MessageBox.Show("Please enter your Age!", "Caption", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation);
}
while(emailTextBox.Text.Length <= 0)
{
MessageBox.Show("Please enter your E-mail!", "Caption", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation);
}
System.Text.RegularExpressions.Regex emailRegex = new System.Text.RegularExpressions.Regex(#"^[a-zA-Z0-9+_.-]+#[a-zA-Z0-9.-]+$");
while(!emailRegex.IsMatch(emailTextBox.Text))
{
MessageBox.Show("Please enter a valid E-mail!", "Caption", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation);
}
InsVal();
}
public void InsVal()
{
**I am trying to call the SQLConn.cs Functions here**
}
}
}
Movint addParam method/function would not solve the problem since the SqlParam variable is not available in sqlConn class.
the better approach for your goal is to to this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
namespace dbConnectivityTest1
{
public class SQLConn
{
private readonly string _connectionString;
private List<SqlParameter> _paramList;
public SQLConn()
{
_connectionString="Server=ServerName;Database=DatabaseName;User Id=UserID;\r\nPassword=Password;";
_paramList = new List<SqlParameter>();
}
public void AddParams(string tableName, object insVal)
{
SqlParameter sqlparams = new SqlParameter(tableName, insVal);
_paramList.Add(sqlparams);
}
public void sqlQueryCmd(string sqlQuery)
{
using (var sqlConn = new SqlConnection(_connectionString))
{
int recordCount = 0;
string excptnShow = "";
try
{
sqlConn.Open();
SqlCommand sqlCmd = new SqlCommand(sqlQuery, sqlConn);
_paramList.ForEach(p => { sqlCmd.Parameters.Add(p); });
_paramList.Clear();
DataTable sqlDT = new DataTable();
SqlDataAdapter sqlDA = new SqlDataAdapter(sqlCmd);
recordCount = sqlDA.Fill(sqlDT);
}
catch (Exception ex)
{
excptnShow = "Error: \r\n" + ex.Message;
}
finally
{
if (sqlConn.State == ConnectionState.Open)
{
sqlConn.Close();
}
}
}
}
}
}
in this scenario there is no need for Main method since every application can have only one Main method and winForms by default already have one Main method.
secondly, the SQLConn class can have private field of type List,
and a public method called AddParam which its responsibility is to add new params to it.
Lastly, a public SqlQueryCmd method is added to do the rest of the job.
you can now use this class to execute your query like this:
private void button1_Click(object sender, EventArgs e)
{
var sqlConn = new SQLConn();
sqlConn.AddParams("tableName","your Object");
sqlConn.AddParams("tableName","your Object");
sqlConn.AddParams("tableName","your Object");
sqlConn.sqlQueryCmd("Query");
}
I would appreciate some help with async/Task implementation in my Windows Form application.
In this app, I retrieve data from the datacenter SQl server database using WCF services, so part of this code runs on the client and some on the datacenter server where it retrieves the data and returns it. I’d like to optimize the code using async/Task on the clien or server or preferably both. The example code starts with a Windows Form with a button, when the button is clicked it gets a value from the database, displays it and updates a local variable.
I’m not clear if I can simply implement async/Task and Task.Run in the first button click event or whether the code should be cascaded through all methods, or something in between. I'm also not clear on how to handle the wcf service.
I’ve created a simplified example of the code, pretty close to sequentially.
In this code, the return value updates the windows form. I’d like to see how this code is optimized using async/Task await for this purpose and what would be different if the code did not return a value.
public partial class Form1 : Form
{
int returnvalue = 0;
public Form1()
{
InitializeComponent();
}
private void btnGetResult_Click(object sender, EventArgs e)
{
int rowcount = ChangeProductPrice(.05m);
txtResult.Text = rowcount.ToString();
}
private int ChangeProductPrice(decimal priceincrease)
{
int rv = MyData.WebServiceObject.ChangePrice(priceincrease);
UpdateLocalVariables(rv);
return rv;
}
private void UpdateLocalVariables(int rv)
{
returnvalue = rv;
}
}
public static class MyData
{
private static IMyDataWCFService _webserviceobject = null;
public static IMyDataWCFService WebServiceObject
{
get
{
if (_webserviceobject is null)
{
//...code to initialize it
}
return _webserviceobject;
}
}
}
[ServiceContract(SessionMode = SessionMode.Required)]
public interface IMyDataWCFService
{
[OperationContract]
int ChangePrice(decimal priceincrease);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class MyDataWCFService : IMyDataWCFService
{
private MyDataService _serviceObject = null;
private MyDataService ServiceObject
{
get
{
if (_serviceObject == null)
{
_serviceObject = new MyDataService();
}
return _serviceObject;
}
}
public int ChangePrice(decimal priceincrease)
{
return ServiceObject.ChangePrice(priceincrease);
}
}
public class MyDataService //running on server
{
public int ChangePrice(decimal priceincrease)
{
int rows = 0;
SqlConnection conn = null;
try
{
conn = this.GetSqlConnection();
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = conn;
cmd.CommandText = "mysp_UpdatePrice";
cmd.Parameters.Add(new SqlParameter("#Rate", priceincrease));
conn.Open();
rows = cmd.ExecuteNonQuery();
}
}
catch (Exception ex)
{
ProcessError(ex);
}
finally
{
if (conn != null)
ReturnSqlConnection(conn);
}
return rows;
}
private SqlConnection GetSqlConnection()
{
//dostuff;
return new SqlConnection();
}
private void ProcessError(Exception ex)
{
//dostuff;
}
private void ReturnSqlConnection(SqlConnection conn)
{
//dostuff;
}
}
I have a program where the user has to login, so they have a id and password. The database with the user login details are stored in a local .mdf file.
I would like to set it up so that whilst the user is logged in, the rest of the program shows their details in the top right corner, so for example their name and their id.
I unfortunately have no idea how to do this and all I have seen whilst I browsed around is people using the actual System login, which is not what I want.
Code for login form:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace InventoryManager
{
public partial class frmLogin : Form
{
public frmLogin()
{
InitializeComponent();
}
private void frmLogin_Load(object sender, EventArgs e)
{
this.AcceptButton = btnSubmit;
}
string cs = #"Data Source= (LocalDB)\v11.0;AttachDbFilename=|DataDirectory|Users.mdf;Integrated Security = True;";
private void btnSubmit_Click(object sender, EventArgs e)
{
if (txtUserID.Text == "" || txtPassword.Text == "")
{
MessageBox.Show("Please enter a User ID and Password");
return;
}
try
{
SqlConnection con = new SqlConnection(cs);
SqlCommand cmd = new SqlCommand("SELECT * FROM tbl_Login WHERE UserID = #userid AND Password = #password", con);
cmd.Parameters.AddWithValue("#userid", txtUserID.Text);
cmd.Parameters.AddWithValue("#password", txtPassword.Text);
con.Open();
SqlDataAdapter adapt = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
adapt.Fill(ds);
con.Close();
int count = ds.Tables[0].Rows.Count;
if (count == 1)
{
MessageBox.Show("Login Successful!");
this.Hide();
frmOverview fo = new frmOverview();
fo.Show();
}
else
{
MessageBox.Show("Login Failed");
txtPassword.Text = "";
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
You can make some static class like this one
public static class LoggedUser
{
public static string Name { get; set; }
public static string Username { get; set; }
}
after successful login, populate that class with data (in example):
if (count == 1)
{
MessageBox.Show("Login Successful!");
LoggedUser.Name = ds.Tables[0].Rows[1].ToString();
LoggedUser.Username = ds.Tables[0].Rows[2].ToString();
this.Hide();
frmOverview fo = new frmOverview();
fo.Show();
}
later, you can use data stored in LoggedUser class on every form in your project...
I trying to develop a windows form application. In here I want to call a variable both form 1 and form 2. I got the vale to ComputerId variable.
namespace ComData
{
public partial class addnew : Form
{
string ConnString = "Server=localhost;Database=machinedetails;UID=root;Encrypt=true;";
public int ComputerId { get; set; }
public addnew()
{
InitializeComponent();
}
private void btnnext_Click(object sender, EventArgs e)
{
using (MySqlConnection conn = new MySqlConnection(ConnString))
{
using (MySqlCommand comm = new MySqlCommand())
{
if (this.txtbranch.Text != "" && this.txtcostcenter.Text != "")
{
try
{
MySqlParameter branchparam = new MySqlParameter("#branch", MySqlDbType.VarChar, 16);
MySqlParameter costcenterparam = new MySqlParameter("#costcenter", MySqlDbType.VarChar, 16);
comm.Connection = conn;
conn.Open();
comm.CommandText = "INSERT INTO computerdetails(branch,costcenter) VALUES (#branch, #costcenter);Select last_insert_id();";
comm.Parameters.Add(branchparam);
comm.Parameters.Add(costcenterparam);
comm.Prepare();
String branch = txtbranch.Text;
String costcenter = txtcostcenter.Text;
comm.Parameters[0].Value = branch;
comm.Parameters[1].Value = costcenter;
MySqlDataReader reader = comm.ExecuteReader();
if (reader.HasRows)
{
reader.Read();
ComputerId = Convert.ToInt32(reader[0]);
MessageBox.Show("value is" + ComputerId);
}
this.Hide();
newdetails nd = new newdetails();
nd.ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
else
{
MessageBox.Show("Please fill the values");
}
}
}
}
}
}
I want to know how to call this ComputerId variable in form 2. Please help me.. Thanks..
This code-block belongs to the form2 where you open your addnew-form
addnew testObj = new addnew(); //init
testObj.show() //or testObj.showDialog();
int id = testObj.ComputerId; //getting the id
You can add a parameterized constructor to newdetails form. And then pass the integer value there. Something like this:
// In newdetails form
private int computerId;
public newdetails(int compId){
computerId = compId;
}
// in addnew form
newdetails nd = new newdetails(ComputerId);
In newdetails form:
private addNew _addNew { get; set; }
public newdetails(addNEw parent)
{
InitializeComponent();
_addNew = parent;
}
//you can access any public variable at addNew form with:
int test = _addNew.PublicVariableName
in your addnew form:
newetails x = new newdetails(this);
x.Show();
I will recommend you to move the ComputerId variable to "Program Class" inside Program.cs file, like this:
public class Program
{
public static int ComputerId;
//Main and other methods......
}
Now you can access this variable from all of your forms simply like this:
int cid=Program.ComputerId;
As Simple As That.
In login form, When I login as Jack which exist in the DOCTOR table, it will go to page_two. I want to disable nurse button 1, and nurse button 2 since Jack is not a nurse but a doctor. Then for the opposite, if I login as Mary, which exist in the NURSE table, it will go to page_two. I want to disable doctor button 1, and doctor button 2 since Mary is not a doctor but a nurse.
The button names for Page_two is btnDoctor1, btnDoctor2, btnNurse1 and btnNurse2
//login Form codes
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Configuration;
namespace GRP_02_03_SACP
{
public partial class page_one : Form
{
public page_one()
{
InitializeComponent();
}
private void page_one_Load(object sender, EventArgs e)
{
}
private void btnLogin_Click(object sender, EventArgs e)
{
//retrieve connection information info from App.config
string strConnectionString = ConfigurationManager.ConnectionStrings["sacpConnection"].ConnectionString;
//STEP 1: Create connection
SqlConnection myConnect = new SqlConnection(strConnectionString);
//STEP 2: Create command
string strCommandtext = "SELECT dUsername, dPassword from DOCTOR";
// Add a WHERE Clause to SQL statement
strCommandtext += " WHERE dUsername=#dname AND dPassword=#dpwd;";
strCommandtext += "SELECT nUsername, nPassword from NURSE WHERE nUsername=#nname AND nPassword=#npwd;";
SqlCommand cmd = new SqlCommand(strCommandtext, myConnect);
cmd.Parameters.AddWithValue("#dname", textUsername.Text);
cmd.Parameters.AddWithValue("#dpwd", txtPassword.Text);
cmd.Parameters.AddWithValue("#nname", textUsername.Text);
cmd.Parameters.AddWithValue("#npwd", txtPassword.Text);
try
{
// STEP 3: open connection and retrieve data by calling ExecuteReader
myConnect.Open();
// STEP 4: Access Data
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read()) //For Doctor
{
if (MessageBox.Show("Login Successful") == DialogResult.OK)
{
page_two form = new page_two();
form.Show();
return;
}
}
reader.NextResult();
while (reader.Read()) //For Nurse
{
if (MessageBox.Show("Login Successful") == DialogResult.OK)
{
page_two form = new page_two();
form.Show();
return;
}
}
//STEP 5: close connection
reader.Close();
MessageBox.Show("Invalid username or password");
}
catch (SqlException ex)
{
}
finally
{
//STEP 5: close connection
myConnect.Close();
}
}
}
}
I suggest you to create some Person class to hold person data:
public class Person
{
public string Name { get; set; }
public JobPosition Position { get; set; }
// etc
}
Where Position is a enum for job positions available for your persons:
public enum JobPosition
{
Doctor,
Nurse
}
Next step will be separating data access logic from presentation code by moving database queries to some repository class:
public class PersonRepository
{
public Person GetPerson(string userName, string password)
{
// execute query and create Person instance
}
}
Also I'd create separate login form which should be shown before your main form starts. It should use PersonRepository to get Person instance which should be passed to MainForm constructor:
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
LoginForm loginForm = new LoginForm();
if (loginForm.ShowDialog() != DialogResult.OK)
return;
Application.Run(new MainForm(loginForm.Person));
On main form use position of logged in person to enable or disable controls:
public partial class MainForm : Form
{
private Person _person;
public MainForm(Person person)
{
InitializeComponent();
_person = person;
}
private void MainForm_Load(object sender, EventArgs e)
{
fooButton.Enabled = (_person.Position == JobPosition.Doctor);
// etc
}
}