How to add items to combobox from another class - c#

How can I add items to my comboBox which is in Form1, but the funcion that add items to that combo box is in another class ?
public void comboBox1_Categories_Load()
{
SqlConnection con = new SqlConnection(connection_string);
string select_string = "SELECT * FROM dbo.Categories";
SqlCommand cmd = new SqlCommand(select_string, con);
SqlDataReader myReader;
con.Open();
myReader = cmd.ExecuteReader();
while (myReader.Read())
{
comboBox1.Items.Add(myReader[1]);
}
myReader.Close();
con.Close();
}

Form:
public partial class Form1 : Form
{
private BusinessLayer _businessLayer ;
public Form1()
{
InitializeComponent();
_businessLayer = new BusinessLayer();
}
private void button1_Click(object sender, EventArgs e)
{
var categories = _businessLayer.GetCategories();
comboBox1.DataSource = categories;
}
}
Business Class:
class BusinessLayer
{
private DataLayer _dataLayer;
public BusinessLayer()
{
_dataLayer = new DataLayer();
}
internal List<string> GetCategories()
{
return _dataLayer.RetrieveCatagories();
}
}
Data Layer (you can refactor and extract the connection to another method):
class DataLayer
{
public const string ConnectionString = "my connection string";
internal List<string> RetrieveCatagories()
{
List<string> items = new List<string>();
using (SqlConnection con = new SqlConnection(ConnectionString))
{
string select_string = "SELECT * FROM dbo.Categories";
SqlCommand cmd = new SqlCommand(select_string, con);
con.Open();
SqlDataReader myReader = cmd.ExecuteReader();
while (myReader.Read())
{
items.Add(myReader[1].ToString());
}
myReader.Close();
}
return items;
}
}

You can something like this:
public static OtherClass()
{
public void RetrieveData(ComboBox comboBox)
{
SqlConnection con = new SqlConnection(connection_string);
string select_string = "SELECT * FROM dbo.Categories";
SqlCommand cmd = new SqlCommand(select_string, con);
SqlDataReader myReader;
con.Open();
myReader = cmd.ExecuteReader();
while (myReader.Read())
{
comboBox.Items.Add(myReader[1]);
}
myReader.Close();
con.Close();
}
}
//then the class where your form is
public void comboBox1_Categories_Load()
{
OtherClass.RetrieveData(comboBox1);
}

Related

How get combobox text value with database in c#

I want to select an item from a combobox and it should show the item that has been selected.
When I use:
cmd.Parameters.AddWithValue("#ItemCateg", categCB.SelectedIndex);
it will only show the number of the item
if I use
cmd.Parameters.AddWithValue("#ItemCateg", categCB.SelectedItem);
or
cmd.Parameters.AddWithValue("#ItemCateg", categCB.SelectedItem.ToString());
It will only print a message like "System.Data.DataRowView"
Here's the whole Code:
private void GetCategory()
{
Con.Open();
SqlCommand cmd = new SqlCommand("Select * from CategoryTBL", Con);
SqlDataReader Rdr;
Rdr = cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Columns.Add("CategoryName", typeof(String));
dt.Load(Rdr);
categCB.ValueMember = "CategoryName";
categCB.DataSource = dt;
Con.Close();
}
private void addbtn_Click(object sender, EventArgs e)
{
if (itemIDtxt.Text == "" || itemnametxt.Text == "" || descriptiontxt.Text == "" || manufacturertxt.Text == "" || amounttxt.Text == "" || quantitytxt.Text == "")
{
MessageBox.Show("Missing Data");
}
else
{
int tAmount = Convert.ToInt32(amounttxt.Text) * Convert.ToInt32(quantitytxt.Text);
try
{
Con.Open();
SqlCommand cmd = new SqlCommand("insert into ItemDetailTBL values(#iID, #ItemNa, #ItemCateg, #ItemDesc, #ItemMan, #ItemAmoun, #ItemQua, #ItemExDate, #ItemtAmount)", Con);
cmd.CommandType = CommandType.Text;
Int32.Parse(itemIDtxt.Text);
cmd.Parameters.AddWithValue("#iID", itemIDtxt.Text);
cmd.Parameters.AddWithValue("#ItemNa", itemnametxt.Text);
cmd.Parameters.AddWithValue("#ItemCateg", categCB.SelectedIndex);
cmd.Parameters.AddWithValue("#ItemDesc", descriptiontxt.Text.ToString());
cmd.Parameters.AddWithValue("#ItemMan", manufacturertxt.Text);
cmd.Parameters.AddWithValue("#ItemAmoun", amounttxt.Text);
cmd.Parameters.AddWithValue("#ItemQua", quantitytxt.Text);
cmd.Parameters.AddWithValue("#ItemExDate", expdatepick.Text);
cmd.Parameters.AddWithValue("#ItemtAmount", tAmount);
cmd.ExecuteNonQuery();
MessageBox.Show("New Data Has been Added to the Inventory");
Con.Close();
Showitem();
addHis();
}
catch (Exception Ex)
{
MessageBox.Show(Ex.Message);
}
}
}
Here is a pattern to following. Create a class representing the category table and override ToString with what should be shown in the ComboBox.
public class Category
{
public int CategoryID { get; set; }
public string CategoryName { get; set; }
public override string ToString() => CategoryName;
}
Rewrite you code to read data to this pattern
public static List<Category> Categories()
{
List<Category> list = new List<Category>() ;
using var cn = new SqlConnection(ConnectionString);
using var cmd = new SqlCommand { Connection = cn,
CommandText = "SELECT CategoryID ,CategoryName FROM dbo.Categories" };
cn.Open();
var reader = cmd.ExecuteReader();
while (reader.Read())
{
list.Add(new Category() { CategoryID = reader.GetInt32(0), CategoryName = reader.GetString(1) });
}
return list;
}
The method above for this example resides in a class named SqlServerOperations.
Form code
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
categCB.DataSource = SqlServerOperations.Categories();
}
private void GetCurrentCategoryButton_Click(object sender, EventArgs e)
{
var current = (Category)categCB.SelectedItem;
MessageBox.Show($"{current.CategoryID,-5}{current.CategoryName}");
}
}

Passing logged in user information to another form c# mysql

For example I want to display the logged in user's information from database to another form like firstname and lastname I got no problem in admin because it only has one form or details for it. I tried passing the text in textbox username to another form and then select the passed text to display the other information of it but it won't, here's my code btw.
private void button2_Click(object sender, EventArgs e)
{
int i = 0;
MySqlCommand comm = con.CreateCommand();
comm.CommandText = "select * from accountinfo where username = #user and pass = #password";
comm.Parameters.AddWithValue("#user", textBox1.Text);
comm.Parameters.AddWithValue("#password", textBox2.Text);
MySqlDataReader myReader;
con.Open();
comm.ExecuteNonQuery();
myReader = comm.ExecuteReader();
string accountType = string.Empty;
DataTable dt = new DataTable();
MySqlDataAdapter da = new MySqlDataAdapter(comm);
i = Convert.ToInt32(dt.Rows.Count.ToString());
while (myReader.Read())
{
i = i + 1;
accountType = myReader["accountType"].ToString();
}
if (i == 0)
{
MessageBox.Show("Wrong username or password!");
}
else if (accountType == "admin")
{
MessageBox.Show("Welcome admin");
this.Hide();
textBox1.Text = string.Empty;
textBox2.Text = string.Empty;
Form3 frm3 = new Form3();
frm3.Show();
}
else
{
MessageBox.Show("Welcome");
this.Hide();
using(var frm4 = new Form4())
{
frm4.FirstName = textBox1.Text;
frm4.ShowDialog();
}
}
con.Close();
}
and my code in second form
public partial class Form4 : Form
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string CellNo { get; set; }
public Form4()
{
InitializeComponent();
}
private void Form4_Load(object sender, EventArgs e)
{
tbUser.Text = FirstName;
try
{
string MyConnection2 = "server=localhost;user id=root;database=account;persistsecurityinfo=True;PASSWORD=test123;SslMode=none";
string Query = "SELECT firstname = '" + tbFN.Text + "' from accountinfo WHERE username = '" + tbUser + "' " ;
MySqlConnection MyConn2 = new MySqlConnection(MyConnection2);
MySqlCommand MyCommand2 = new MySqlCommand(Query, MyConn2);
MySqlDataAdapter MyAdapter = new MySqlDataAdapter();
MyAdapter.SelectCommand = MyCommand2;
DataTable dTable = new DataTable();
MyAdapter.Fill(dTable);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
Logged in user information is kind of static for all your application, so you should be able to access to it from anywhere
As a solution create class user
public class User {
username, full name ...
}
Create embiend class ApplicationContext
public class ApplicationContext
{
private ApplicationContext(){
}
public User UserInfo {get;}
public static ApplicationContext Current{get;}
public static Init(User userInfo)
{
if(Current != null)
throw new Exception("Context already initialized");
Current = new ApplicationContext(){
UserInfo = userInfo
}
}
}
After login call
ApplicationContext.Init(userInfo);
Everywhere where you need user info call
ApplicationContext.Current.UserInfo

Save data in Form2 with Account ID in 1 column to see who's owning that data

I ideally wanted to make so that when the user is logged in and have gone to form2. That when they write new data and press save to save the data in the mysql database With their account ID in 1 column but I couldn't figure out how to do that so I am turning here for help.
Form1 relevant code:
MySqlConnection con = new MySqlConnection("server=SERVERIP;port=3306;database=DATABASE;uid=USERNAME;password=PASSWORD");
MySqlCommand cmd = new MySqlCommand("SELECT * FROM account WHERE username='" + this.user_txt.Text + "' AND pass='" + this.password_txt.Text + "';", con);
MySqlDataReader MyReader;
con.Open();
MyReader = cmd.ExecuteReader();
int count = 0;
while (MyReader.Read())
{
count = count + 1;
}
if (count == 1)
{
this.Hide();
var form1 = new Form2();
form1.Show();
}
Form2 relevant code:
using (MySqlConnection con = new MySqlConnection("server=SERVERIP;port=3306;database=DATABASE;uid=USERNAME;password=PASSWORD"))
{
con.Open();
using (MySqlCommand cmd = new MySqlCommand("insert into info(Datum,Timmar,Rast) Values(#Datum,#Timmar,#Rast)", con))
{
DateTime now = DateTime.Now;
cmd.Parameters.AddWithValue("#Datum", now);
cmd.Parameters.AddWithValue("#Timmar", textBox2.Text);
cmd.Parameters.AddWithValue("#Rast", textBox3.Text);
cmd.ExecuteNonQuery();
MessageBox.Show("Sparat!");
con.Close();
}
}
So what I want todo is to add account id with that information from form2 into the database.
something like:
using (MySqlCommand cmd = new MySqlCommand("insert into info(AccountId,Datum,Timmar,Rast) Values(#AccountId,#Datum,#Timmar,#Rast)", con))
{
DateTime now = DateTime.Now;
cmd.Parameters.AddWithValue("#AccountId", ACCOUNT_ID_SOURCE);
cmd.Parameters.AddWithValue("#Datum", now);
cmd.Parameters.AddWithValue("#Timmar", textBox2.Text);
cmd.Parameters.AddWithValue("#Rast", textBox3.Text);
cmd.ExecuteNonQuery();
MessageBox.Show("Sparat!");
con.Close();
}
now I have tried to use to get the user input that they typed to form2 with no luck.
var frm1 = new Form1(); //Form2
string ACCOUNT_ID_SOURCE = frm1.UserText; //Form2
public string UserText { get; private set; } //form1
UserText = this.user_txt.Text; //form1
any ideas on how to fix this?
How about this one?
Sol 1. Set a userid as a Form2's constructor parameter.
readonly string ACCOUNT_ID_SOURCE;
public Form2(string aUserID)
{
InitializeComponent();
ACCOUNT_ID_SOURCE = aUserID;
}
Sol 2. Make user information static class.
1) Class
public class UserInfo
{
public static UserInfo instance = new UserInfo();
public string LogInID { get; set; }
}
2) Form 1
UserInfo.instance.LogInID = "MyID";
3) Form 2
UserInfo.instance.LogInID; // Use this property
try this create a new class
public class UserModel
{
public int IdUser { get; set; }
public string UserName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
then in form1 in a button click event
private void button1_Click(object sender, EventArgs e)
{
UserModel userModel = new UserModel();
using (SqlConnection conn = new SqlConnection(#"Data Source=localhost; Initial Catalog=Northwind; Integrated Security=True"))
{
//here your code to retrieve data from database
userModel.FirstName = "";
userModel.LastName = "";
userModel.IdUser = 1;
}
Form2 frm2 = new Form2(userModel);
this.Hide();
frm2.Show();
}
and in your form2
public partial class Form2 : Form
{
private UserModel UserObject { get; set; }
public Form2()
{
InitializeComponent();
}
public Form2(UserModel userModel)
{
InitializeComponent();
this.UserObject = userModel;
}
private void btnSaveData_Click(object sender, EventArgs e)
{
using (MySqlCommand cmd = new MySqlCommand("insert into info(AccountId,Datum,Timmar,Rast) Values(#AccountId,#Datum,#Timmar,#Rast)", con))
{
DateTime now = DateTime.Now;
cmd.Parameters.AddWithValue("#AccountId", UserObject.IdUser);
cmd.Parameters.AddWithValue("#Datum", now);
cmd.Parameters.AddWithValue("#Timmar", textBox2.Text);
cmd.Parameters.AddWithValue("#Rast", textBox3.Text);
cmd.ExecuteNonQuery();
MessageBox.Show("Sparat!");
con.Close();
}
}
}

How Can I create executeReader class

Sir,
I have a connection class for ExecuteNonquery
public class Connection
{
SqlConnection conn;
SqlCommand cmd;
public void connclose()
{
conn.Close();
}
public Connection()
{
conn = new SqlConnection(#"server=ADMIN-PC;database=sample;Integrated security=true");
cmd = null;
}
public void nonquery(SqlCommand cmd)
{
conn.Open();
cmd.Connection = conn;
cmd.ExecuteNonQuery();
conn.Close();
}
In this same way I have to create a Executereader class also....What changes i should apply for that
I have a class too
public void insert(string sid, string cid, string state)
{
SqlCommand cmd = new SqlCommand("InsertState");
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#StateId", SqlDbType.VarChar).Value = sid;
cmd.Parameters.Add("#CountryId", SqlDbType.VarChar).Value = cid;
cmd.Parameters.Add("#State", SqlDbType.VarChar).Value = state;
conn.nonquery(cmd);
}
You may add this method
public SqlDataReader ReadMe(SqlCommand cmd)
{
conn.Open();
cmd.Connection = conn;
SqlDataReader reader = cmd.ExecuteReader();
return reader;
}
You can call it like this :
SqlCommand cmd = new SqlCommand("reading");
cmd.CommandType = CommandType.StoredProcedure;
using(SqlDataReader ourreader = conn.ReadMe(cmd))
{
while (ourreader.Read())
{
//some code
}
}
conn.Close();

combine two methods returning two different values

Hi I have got two methods are returning two different return type of values like int and string and I am executing query inside the method with passing different variables like the below
METHOD 1
private string SelectTransactionHistory(int transactionId, ContextObject contextObject)
{
SqlConnection con;
SqlCommand cmd;
con = new SqlConnection(contextObject.ConnectionString);
con.Open();
string returnvalue = string.Empty;
string selecteQuery = "SELECT Comments
From dbo.TransactionHistory
WHERE TransactionID = '" + transactionId + "'";
cmd = new SqlCommand(selecteQuery, con);
returnvalue = (string)cmd.ExecuteScalar();
con.Close();
return returnvalue;
}
METHOD 2
private int SelectTransactionHistoryID(string comment, ContextObject contextObject)
{
SqlConnection con;
SqlCommand cmd;
con = new SqlConnection(contextObject.ConnectionString);
con.Open();
string query = "SELECT TransactionID
From dbo.TransactionHistory
WHERE Comments = '" + comment + "'";
cmd = new SqlCommand(query, con);
int returnvalue = (int)cmd.ExecuteScalar();
con.Close();
return returnvalue;
}
I am calling these methods in another method like this
int transactionId = SelectTransactionHistoryID(comment, GetContext());
string commentsreturnValue = SelectTransactionHistory(transactionId, GetContext());
how can i combine these two methods to make more generic type..
Would any one have any suggestions on how to do this..
Many Thanks.....
You could create a method to execute any query using ado.net, for sample:
private static T ExecuteQuery<T>(ContextObject contextObject, string query)
{
T result;
using (SqlConnection con = con = new SqlConnection(contextObject.ConnectionString))
{
try
{
con.Open();
using (SqlCommand cmd = cmd = new SqlCommand(query, con))
{
result = (T)cmd.ExecuteScalar();
}
}
catch
{
result = null;
}
finally
{
con.Close();
}
}
returnr result;
}
And pass a query that return a single value (in sql we use TOP 1), something like this:
var resultComment = ExecuteQuery<string>("SELECT TOP 1 Comments From dbo.TransactionHistory WHERE TransactionID = '" + transactionId + "'");
var resultTransactionId = ExecuteQuery<int>("SELECT TOP 1 TransactionID From dbo.TransactionHistory WHERE Comments = '" + comment + "'")
I have all of my infrastructure classes setup to utilize Dapper. However you can replace the dapper extension method with a regular method.
Base Service:
public interface IService
{
T Execute<T>(Func<IDbConnection, T> query);
void Execute(Action<IDbConnection> query);
}
public sealed class Service : IService
{
private readonly string _connectionString;
public Service(string connectionString)
{
_connectionString = connectionString;
}
private IDbConnection CreateConnection()
{
var connection = new SqlConnection(_connectionString);
connection.Open();
return connection;
}
public T Execute<T>(Func<IDbConnection, T> query)
{
using (var connection = CreateConnection())
{
return query(connection);
}
}
public void Execute(Action<IDbConnection> query)
{
using (var connection = CreateConnection())
{
query(connection);
}
}
}
DTO:
public class TransactionHistory
{
public int TransactionID { get; set; }
public string Comments { get; set; }
}
Service:
public interface ITransactionHistoryService
{
IEnumerable<TransactionHistory> GetByTransactionId(int transactionId);
IEnumerable<TransactionHistory> GetByComment(string comment);
}
public sealed class TransactionHistoryService : ITransactionHistoryService
{
// Note SELECT * is frowned upon. Replace with actual column names.
private const string GetByTransactionIdQuery =
"SELECT * FROM dbo.TransactionHistory WHERE TransactionID = #TransactionId";
private const string GetByCommentQuery =
"SELECT * FROM dbo.TransactionHistory WHERE Comments = #Comment";
private readonly IService _service;
public TransactionHistoryService(IService service)
{
_service = service;
}
public IEnumerable<TransactionHistory> GetByTransactionId(int transactionId)
{
var result = _service.Execute(c =>
c.Query<TransactionHistory>(GetByTransactionIdQuery,
new { TransactionId = transactionId }));
return result;
}
public IEnumerable<TransactionHistory> GetByComment(string comment)
{
var result = _service.Execute(c =>
c.Query<TransactionHistory>(GetByCommentQuery,
new { Comment = comment }));
return result;
}
}
You can create a single function as follows- (Not tested)
private string[] SelectTransactionHistory(int transactionId, ContextObject contextObject)
{
string[] returnValues;
SqlConnection con;
SqlCommand cmd;
SqlDataReader reader;
con = new SqlConnection(contextObject.ConnectionString);
con.Open();
string returnvalue = string.Empty;
string selecteQuery = "SELECT TransactionID, Comments From dbo.TransactionHistory WHERE TransactionID = '" + transactionId + "'";
cmd = new SqlCommand(selecteQuery, con);
reader = cmd.ExecuteReader();
while(reader.Read())
{
returnValues[0] = reader["TransactionID"].ToString();
returnValues[1] = reader["Comments"].ToString();
}
con.Close();
return returnValues;
}
And then call it as follows-
string[] TransactionHistory = SelectTransactionHistory(transactionId, GetContext());
int transactionId = Convert.ToInt32(TransactionHistory[0]);
string commentsreturnValue = TransactionHistory[1];
The above code is not tested. But you can get an idea.

Categories