I have a class where I have a method that is creating a connection string.I want to access that connection string from other windows,but that isn't working.This is my code so far:
My main login is just calling the method from a class on a button click
private void button_Click(object sender, RoutedEventArgs e)
{
Class1 kl = new Class1();
kl.SQLCon(textBox, textBox_Copy);
}
My class looks like this:
class Class1
{
string user = string.Empty;
string pass = string.Empty;
private string ConString = string.Empty;
public string User { get { return this.ConString; } set { this.ConString = value; } }
public void SQLCon(TextBox tb1,TextBox tb2)
{
user = tb1.Text;
pass = tb2.Text;
if (string.IsNullOrWhiteSpace(user) || string.IsNullOrWhiteSpace(pass))
{
MessageBox.Show("Popuni sva polja");
return;
}
SqlConnection con;
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
builder.DataSource = "DESKTOP";
builder.InitialCatalog = "Manager";
builder.IntegratedSecurity = false;
builder.UserID = user;
builder.Password = pass;
try
{
using (con = new SqlConnection(builder.ToString()))
{
con.Open();
if ((con != null && con.State == System.Data.ConnectionState.Open))
{
ConString = builder.ToString();
MessageBox.Show("Uspesno logovan!" + ConString);
Window1 win = new Window1();
win.ShowDialog();
}
}
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message);
}
}
}
Now when from the Window1 I call the method to get ConString,I get nothing,blank.The problem is that it is not looking in the SQLCon for the string value,it is looking it as it is defined at the beggining of the class.
I can get this to work with this solution: before calling ShowDialog,I can have a string in the Window1, that I can pass this value, something like win.stringCon = ConString,and this works.But I want to be able to do this:
Window1 code:
private void button_Click(object sender, RoutedEventArgs e)
{
Class1 myClass = new Class1();
string conn = myClass.User;
MessageBox.Show(conn);
}
SOLUTION: You can't do it the way I imagined. But here is what you can do.
You define a string (conString) in the Window1 that will be you connection string.And you put this line before you call win.ShowDialog():
mw.conString = conString;
This way you have the string in your new window.And with one line you can transport the value from Window1 to some other Window that you will open next.
Related
I've got four main files in play here: Form 1, which is called frmLogin, Form2, which is called frmUserHome, a class called DbConnector.cs and a class called BankAccount.cs
The program works as follows: Form1 calls method from DBConnector -> DB Connector method fills an object and it's variables which is instantiated in DBConnector. This object is of class BankAccount.cs
Then, after the method finishes and if successful, Form1 instantiates Form2 and it opens. In form2 is where I want to access the object that was created in the DBconnector class. How do I do this? I've tried instantiating new objects of BankAccount.cs in there, I've tried all these different constructor stuff I've seen on here. Nothing seems to be working.
For reference: the object is populated when it runs in Dbconnector. However, when I try to receive data when I use it in Form2, all of the fields are NULL.
I've made countless adjustments from reading different posts on here so the code is rightfully a mess now and probably extremely unorganised.
Here's the main portions of my code below:
Form1
namespace BankingSystem
{
public partial class frmLogIn : Form
{
public BankAccount myBankAccount = new BankAccount();
dbConnector newConnector;
public frmLogIn()
{
InitializeComponent();
timerMain.Enabled = true;
timerMain.Start();
}
private void btnLogIn_Click(object sender, EventArgs e)
{
try
{
newConnector.CheckDetailsLogin(accountNumTextBox.Text, pinNumTextBox.Text);
frmUserHome UserHome = new frmUserHome();
MessageBox.Show("Success! Happy Banking!");
UserHome.ShowDialog();
}
catch
{
MessageBox.Show("Failed - incorrect login details.");
}
}
}
}
DBConnector Class:
namespace BankingSystem
{
public class dbConnector
{
Boolean isCorrect = false;
private static SQLiteConnection sqlconnConnection;
public BankAccount myBankAccount = new BankAccount();
public DataSet myAppDataSet = new DataSet(); // created for you to use and push data into
public dbConnector(string strFilePath)
{
try
{
sqlconnConnection = new SQLiteConnection("Data Source=" + strFilePath);
}
catch (Exception ex)
{
throw new Exception("DbConnector initialisation unsuccessful:\n" + ex.Message);
}
}
public void CheckDetailsLogin(string strAccno, string strPin)
{
// this is where check ou the boiler plate code and adjst to my APP.
try
{
DataTable dtUser = new DataTable();
sqlconnConnection.Open();
string strQuery2 = #"SELECT * FROM Accounts WHERE Account_Number='"+ strAccno +"' AND PIN='"+ strPin +"';"; // example of a parametrised SQL statement.
SQLiteCommand sqlcomCommand2 = new SQLiteCommand(strQuery2, sqlconnConnection);
SQLiteDataAdapter sqldatadptAdapter = new SQLiteDataAdapter(sqlcomCommand2); // local SQL data Adaptor
try
{
sqldatadptAdapter.Fill(dtUser);
}
catch (Exception ex)
{
// Exception will the "thrown"/Raised when there was a problem
throw new Exception($"SELECT unsuccessful:\n{ex.Message}");
}
finally
{
sqlconnConnection.Close();
}
if (dtUser.Rows.Count == 0)
{
// the record set comes back with no records found, an empty Datatable with no rows
// means there was no data matching your query
throw new Exception("No Such Bank user found");
}
else
{
// change to your applications needs
// Rows[0] - we are expecting at least 1 row, and its basically an array so we address
// the first element with 0
// Rows[0]["fieldnamefromDB"] <- referencing the column in the DB
//this.strID = strUserID;
myBankAccount.AccountNumber = dtUser.Rows[0]["Account_Number"].ToString();
myBankAccount.AccountPin = dtUser.Rows[0]["PIN"].ToString();
myBankAccount.AccountBalance = Convert.ToDecimal(dtUser.Rows[0]["Balance"]);
myBankAccount.AccountHolder = dtUser.Rows[0]["First_Name"].ToString();
myBankAccount.AccountAddress = dtUser.Rows[0]["Home_Address"].ToString();
myBankAccount.MyAccountGUID = dtUser.Rows[0]["GUID"].ToString();
if (myBankAccount.AccountNumber == strAccno && myBankAccount.AccountPin == strPin)
{
isCorrect = true;
}
else
{
isCorrect = false;
}
//myLocalBankAccUsr
}
}
catch (Exception ex)
{
// exception thrown for the whole method or function
throw new Exception($"User(string):\n{ex.Message}");
}
}
BankAccount.cs class
namespace BankingSystem
{
public class BankAccount
{
private string accountNumber;
private decimal accountBalance;
private string accountHolder;
private string accountPhoneNumber;
private string accountAddress;
private string accountPin;
private string myAccountGUID;
// private string AccountHolderGUID;
// private string AccountTypeGUID;
public string AccountNumber
{
get { return accountNumber; }
set { accountNumber = value; }
}
public decimal AccountBalance
{
get { return accountBalance; }
set { accountBalance = value; }
}
public string AccountHolder
{
get { return accountHolder; }
set { accountHolder = value; }
}
public string AccountPhoneNumber
{
get { return accountPhoneNumber; }
set { accountPhoneNumber = value; }
}
public string AccountAddress
{
get { return accountAddress; }
set { accountAddress = value; }
}
public string AccountPin
{
get { return accountPin; }
set { accountPin = value; }
}
public string MyAccountGUID
{
get { return myAccountGUID; }
set { myAccountGUID = value; }
}
public Boolean CanWithDrawAmount(decimal AmountToTransfer)
{
if (AmountToTransfer > this.AccountBalance){
return false;
}else
{
return true;
}
}
public void UpdatePIN()
{
// connect to bank DB connector
// send it the new pin
// SQL update command
}
}
}
Here is Form2:
namespace BankingSystem
{
public partial class frmUserHome : Form
{
public frmUserHome()
{
InitializeComponent();
tabMainForm.Appearance = TabAppearance.FlatButtons;
tabMainForm.ItemSize = new Size(0, 1);
tabMainForm.SizeMode = TabSizeMode.Fixed;
timerMain.Enabled = true;
timerMain.Start();
}
private void frmUserHome_Load(object sender, EventArgs e)
{
labelWelcome.Text = "Welcome "; //newMainBank.AccountHolder;
}
The 'labelWelcome.Text = "Welcome" is where I want the name stored inside the object to be used. So it should ideally access the BankAccount class, access the AccountHolder field and use that field to concat onto the end of the 'Welcome' text. However, it just shows 'Welcome' and no name on the end, when I run the program (because all values get reset to null in form2.. for some reason)
Below I have updated the code for Form1 and Form2.
Form 1
namespace BankingSystem
{
public partial class frmLogIn : Form
{
dbConnector newConnector;
public frmLogIn()
{
InitializeComponent();
newConnector = new dbConnector(**pass str file path**);
timerMain.Enabled = true;
timerMain.Start();
}
private void btnLogIn_Click(object sender, EventArgs e)
{
try
{
newConnector.CheckDetailsLogin(accountNumTextBox.Text, pinNumTextBox.Text);
frmUserHome UserHome = new frmUserHome(newConnector.myBankAccount);
MessageBox.Show("Success! Happy Banking!");
UserHome.ShowDialog();
}
catch
{
MessageBox.Show("Failed - incorrect login details.");
}
}
}
}
Form 2
namespace BankingSystem
{
public partial class frmUserHome : Form
{ public BankAccount _bankAccount;
public frmUserHome(BankAccount bankAccount)
{
InitializeComponent(); _bankAccount = bankAccount;
tabMainForm.Appearance = TabAppearance.FlatButtons;
tabMainForm.ItemSize = new Size(0, 1);
tabMainForm.SizeMode = TabSizeMode.Fixed;
timerMain.Enabled = true;
timerMain.Start();
}
private void frmUserHome_Load(object sender, EventArgs e)
{
labelWelcome.Text = "Welcome "+ bankAccount.AccountHolder;
}
I have a list variable and I created an iterator for it to print out its content. It's working in the console application but when i try to do it using windows form(gui) it doesn't work
PROGRAM.CS
namespace gui
{
static class Program
{
public class studentdata
{
public string id, name, password, academicyear, finishedcourseslist, ipcourseslist;
public int noCoursesF, noCoursesIP;
public List<string> coursesF;
public List<string> coursesIP;
public studentdata()
{
id = "2015123";
password = "Student";
coursesF = new List<string>();
coursesIP = new List<string>();
}
public studentdata(string ID, string NAME, string PASSWORD)
{
id = ID;
}
**public void view_finished_courses()
{
List<string> finished = coursesF;
foreach (string n in finished)
{
finishedcourseslist += n;
}
MessageBox.Show(finishedcourseslist, "Finished courses");
}
public void view_ip_courses()
{
List<string> progress = coursesIP;
foreach (string m in progress)
{
ipcourseslist += m;
}
MessageBox.Show(ipcourseslist, "Finished courses");
}**
}
public class Admin
{
public string name, password;
public Admin()
{
name = "Admin";
password = "Admin";
}
}
//functionssssss
internal static studentdata studentSearch(string IDsearch)
{
FileStream FS = new FileStream("Students.txt", FileMode.Open);
StreamReader SR = new StreamReader(FS);
studentdata std = new studentdata();
while (SR.Peek() != -1)
{
string z = SR.ReadLine();
String[] Fields;
Fields = z.Split(',');
if (IDsearch.CompareTo(Fields[0]) == 0)
{
std.id = Fields[0];
std.password = Fields[1];
std.name = Fields[2];
std.noCoursesF = int.Parse(Fields[3]);
int currentField = 4;
for (int course = 0; course < std.noCoursesF; course++)
{
std.coursesF.Add(Fields[currentField]);
currentField++;
}
std.noCoursesIP = int.Parse(Fields[currentField]);
currentField++;
for (int course = 0; course < std.noCoursesIP; course++)
{
std.coursesIP.Add(Fields[currentField]);
currentField++;
}
std.academicyear = Fields[currentField];
SR.Close();
return std;
}
else continue;
}
SR.Close();
studentdata araf = new studentdata();
return araf;
}
}
FORM.CS
namespace gui
{
public partial class Form3 : Form
{
Program.studentdata student = new Program.studentdata();
public Form3()
{
InitializeComponent();
}
private void label1_Click(object sender, EventArgs e)
{
}
private void button5_Click(object sender, EventArgs e)
{
}
private void button4_Click(object sender, EventArgs e)
{
student.view_finished_courses();
}
private void button6_Click(object sender, EventArgs e)
{
student.view_ip_courses();
}
}
}
The output is an empty message box, I don't know why variable isn't added.
Replace messagebox line with
MessageBox.Show(string.Join(",", coursesF.ToArray()), "Finished courses");
It seems like your code is incomplete. Nowhere in the code which gets executed after you clicked button4 you are adding items to coursesF. It seems that you are adding items in this line: std.coursesF.Add(Fields[currentField]);
This line is in your function studentSearch(IDsearch), the function never gets called.
In this function you got a string z in which all the data of a student is saved (string z = SR.ReadLine()). You must somehow fill this string z. You can use a TextBox in your form and pass the value into the string, use a string from a text file or use the console input(see here: Get input from console into a form).
As you can see the issue is not a one line fix.
In the program you enter with a username brought from a database. I need to pass that username to another form but when I do it, it returns null in the second form although in the first form it appears.( "Jugador" is the class from where I bring the name).
public Usuario()
{
InitializeComponent();
}
private string _Message;
public string Message
{
get { return _Message; }
set { _Message = strName; }
}
public string strName;
private void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text!="")
{
Jugador jug = new Jugador();
jug.Traemelo(textBox1.Text);
strName = textBox1.Text;
elegirTipo us = new elegirTipo();
us.Show();
this.Hide();
}
}
And in my other form i have this.(Usuario is the first form)
private void silabas_Load(object sender, EventArgs e)
{
Usuario usu = new Usuario();
juga.Traemelo(usu.Message);
}
I've got to add that in the middle of these forms I pass by one but doens't need the variable there.
Thanks for the help! I really don't know what is happening because I've done this other times.
// Usuario.cs
public string Message { get; set; }
...
Silabas silabas = new Silabas(this);
// Silabas.cs
public Silabas(Usuario usuario)
{
// Here you can access the usuario.Message
}
What I personally would do is to create a static class and hold the values in it. This would also let me not to instantiate the class every time I need to use it.
public static class Jugador
{
//ctor if needed
public static string Username { get; set; }
}
Now, in your code where you both set or get the values of the username:
//login process
Jugador.Username = "some username";
//in application (get)
textbox1.Text = Jugador.Username;
I believe this is what you are looking for.
At a first glance:
public string Message
{
get { return _Message; }
set { _Message = value } // instead of strName;
}
no Message=something (set is never called)
_Message seems to compete with strName. One variable should be enough.
EDIT: Combined to this:
public Usuario()
{
InitializeComponent();
}
private string _Message;
public string Message
{
get { return _Message; }
set { _Message = value; }
}
private void button1_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(textBox1.Text))
{
Jugador jug = new Jugador();
jug.Traemelo(textBox1.Text);
Message = textBox1.Text;
elegirTipo us = new elegirTipo();
us.Show();
this.Hide();
}
}
Problem is since you are creating a new instance i.e. Usuario usu = new Usuario(); of the object in the other class, the value becomes null. I would use a static variable. In your Usuario class use
public static string strName{get;set;}
Now to set the value say Usuario.strName = textBox1.Text;
in your other class here say,
private void silabas_Load(object sender, EventArgs e)
{
juga.Traemelo(Usuario.strName);
}
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.
I have 2 classes: MyForm and Database
In MyForm I have a method to change a label text to show error:
public void printError(string text){
label1.Text = text;
}
My Database class needs to access that method too, so I make it static:
public static void printError(MyForm form, string text){
form.label1.Text = text;
}
Now the problem is, how do I call that method from Database class?
This question I found said that I need to pass MyForm into Database's contructor like this:
class MyForm : Form{
Database db;
public Form(){
db = new Database(this);
}
}
class Database{
MyForm form;
public Database(MyForm f){
form = f;
}
...
//then I can access the printError like this
MyForm.printError(form, "You got error");
}
I tried that and it freezes the form. Any other solution?
Thanks
Here is a very simple example of how you can achieve this without your data layer knowing about your UI:
class MyForm : Form
{
Database db;
public Form()
{
db = new Database(this);
}
public void DoSomething()
{
var errors = db.Login("", "");
if (errors.Any())
label1.Text = errors.First(); // Or you can display all all of them
}
}
class Database
{
public List<string> Login(string username, string password)
{
var errors = new List<string>();
if (string.IsNullOrEmpty(username))
errors.Add("Username is required");
if (string.IsNullOrEmpty(password))
errors.Add("Password is required");
[...]
return errors;
}
}
Like #Matthew Ferreira and others have stated the design is not idea, but here's something to get you started.
class MyForm : Form
{
public void SomeMethod()
{
var dataAccess = new Repository();
dataAccess.ExecuteQuery();
if (dataAccess.Exceptions.Any())
{
// display your error messages
form.label1.Text = dataAccess.Exceptions.Select(x => x.ToString());
}
}
}
class Repository
{
private readonly HashSet<Exception> _exceptions = new HashSet<Exception>();
public IEnumerable<Exception> Exceptions
{
get { return _exceptions; }
}
public int ExecuteQuery()
{
var numberOfRecordsAffected = 0;
try
{
// do something
}
catch (Exception ex)
{
// normall catching exceptions is a bad idea
// and you should really catch the exception at the
// layer best equiped to deal with it
_exceptions.Add(ex);
}
// but, for the purpose of this example we might want to add some logic to try the query on another database ????
try
{
// do something
}
catch (Exception ex)
{
_exceptions.Add(ex);
}
return numberOfRecordsAffected;
}
}
You need to look up "seperation of concerns". Its really bad to mix your UI code with you Database Access Layer (DAL). Better to bind the UI to business objects that are populated via a DAL.
To let the UI know about an error you could simply use a delegate.
namespace OperationErrorDelegate
{
public delegate void OperationErrorHandler(Exception ex);
public class DAL
{
public event OperationErrorHandler ReportError;
public void DoDALOperationThatCausesError()
{
try
{
int i = 1;
int j = 0;
int k = i/j;
}
catch (Exception ex)
{
ReportError(ex);
}
}
}
}
Add this code to the form:
using System ;
using System.Windows.Forms;
namespace OperationErrorDelegate
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
DAL DAL = new DAL();
DAL.ReportError += new OperationErrorHandler(DAL_OperationErrorProgress);
DAL.DoDALOperationThatCausesError();
}
private void DAL_OperationErrorProgress(Exception ex)
{
label1.Text = ex.Message;
}
}
}
Assuming the OP's requirement is to display an error message in a label, when the credentials are wrong:
private void btn_login_Click(object sender, EventArgs e)
{
MySqlConnection con = new MySqlConnection("server=localhost;uid=root;password=abc;database=mydb");
MySqlCommand cmd = new MySqlCommand("select * from emp where name='" + textBox1.Text + "'and pwd='" + textBox2.Text + "'",con);
con.Open();
MySqlDataReader dr = cmd.ExecuteReader();
if (dr.Read())
{ //successful
//navigate to next page or whatever you want
}
else
Label1.Text("Invalid userid or password");
con.Close();
}
And if you need error message for wrong data type (the user input string but the database column is Integer), then use validations at client side. You dont need to do it at backend, since that will be a burden.
You can use regular expressions for that in the button_click itself.