I am a total noob on C# and I'm stuck on changing the status label text from an other class.
When this class connects to db I want to change the label text to "Connected":
public class DBConnect
{
public void Connect()
{
MySqlConnection conn;
string myConnectionString;
myConnectionString = "server = 127.0.0.1; uid=cardb;" +
"pwd=cardb; database=test;";
try
{
Form form = new Form();
conn = new MySqlConnection();
conn.ConnectionString = myConnectionString;
conn.Open();
form.setStatus();
}
catch (MySqlException ex)
{
MessageBox.Show(ex.Message);
}
}
}
This is the method setStatus I created in Form class:
public partial class Form : System.Windows.Forms.Form
{
public Form()
{
InitializeComponent();
}
public void setStatus()
{
StatusTextLabel.Text = "Connected";
}
The label text doesnt change though.. :/
I see no code to create a DBConnect object, or to call its Connect() method, and no code that makes the Form object visible, e.g. form.Show().
Other than that you probably should not create the Form from the Connect method; instead call Connect() from the Form, e.g. in Form_Load(), let it return a status, or better: the conn object (which you are now throwing away after connection), and make Form_Load set the Label.Text based on that.
Example code:
private void Form1_Load(object sender, EventArgs e)
{
var conn = new DBConnect().Connect();
if (conn != null && conn.State == ConnectionState.Open)
{
StatusTextLabel.Text = "Connected";
}
}
public class DBConnect
{
public SqlConnection Connect()
{
SqlConnection conn = ...
// ...
return conn;
}
}
Instead of creating an instance of a new Form, you probably need an instance of already opened form and call the method from there. You can try:
(System.Windows.Forms.Application.OpenForms["Form"] as Form).setStatus();
Pass the form instead of creating a new one.
private Form form {get;set;}
public DBConnect(Form form)
{
this.form = form;
}
Then try this
form.Invoke(new MethodInvoker(() => form.setStatus()));
Related
What I am trying to do is if for example a user has registered or saved data in the database they will be automatically redirected to a certain form on startup...
Here is the code I've tried so far and it it is not working according to how I want it to be...
In Form1:
// I declared the rowcounts as public
public int rowcounts;
public void Form1_Load(object sender, EventArgs e)
{
SqlConnection connCount = locald.DB.GetSqlConnection();
System.Data.SqlClient.SqlCommand com = new
System.Data.SqlClient.SqlCommand();
com.Connection = connCount;
com.CommandType = CommandType.StoredProcedure;
com.CommandText = #"countval";
rowcounts = Convert.ToInt32(com.ExecuteScalar());
label1.Text = rowcounts.ToString();
}
In Program.cs:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form1 f1 = new Form1();
if (f1.rowcounts == 0)
{
Application.Run(new Form2()); // if database has no records
}
else
{
Application.Run(new Form1());
}
}
I created a class DB.cs for connection
public class DB
{
public static string ConnectionString
{
get
{
string connStr = ConfigurationManager.ConnectionStrings["locald.Properties.Settings.localdConnectionString"].ToString();
SqlConnectionStringBuilder sb = new SqlConnectionStringBuilder(connStr);
sb.ApplicationName = ApplicationName ?? sb.ApplicationName;
sb.ConnectTimeout = (ConnectionTimeout > 0) ? ConnectionTimeout : sb.ConnectTimeout;
return sb.ToString();
}
}
public static string ApplicationName { get; set; }
public static int ConnectionTimeout { get; set; }
public static SqlConnection GetSqlConnection()
{
SqlConnection cnn = new SqlConnection(ConnectionString);
cnn.Open();
return cnn;
}
}
The problem is even if the database has or without data it would still show the Form1 on startup. What I want is if the database has data it would automatically be redirected to the Form1 and if it has not then it will be in Form2 on startup...
Please help.. Thanks in advance...
defects in your program are,
what is f1 ?
i am seeing that you have coded SQL functions in Form1.cs.
why don't you perform all the SQL operations on program.cs
and redirect to the form as per your query result.
follow as below,
program.cs
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
int rowcounts = 0;
SqlConnection connCount = locald.DB.GetSqlConnection();
System.Data.SqlClient.SqlCommand com = new
System.Data.SqlClient.SqlCommand();
com.Connection = connCount;
com.CommandType = CommandType.StoredProcedure;
com.CommandText = #"countval";
rowcounts = Convert.ToInt32(com.ExecuteScalar());
if (rowcounts == 0){
Application.Run(new Form2()); //if database has no records
}
else
{
Application.Run(new Form1());
}
}
Form1.cs
private void Form1_Load()
{
}
I'd post it as a comment, but can't comment with low reputation...
First of all, you're missing "if" in your Program.cs (I believe it's not the real problem, or is it?)
Secondly, you can try to call "Close" on form1 if you don't want it to show, right in its "Initialize", just as an easy solution.
Like that:
private void Form1_Load(object sender, EventArgs e)
{
//...
//Your code
//...
// If no data
this.Close();
}
I am writing a user control. I want it to return a customer number when the user double clicks on the customer. I can't seem to get it to work. The user control is displayed and, on the double click, the data shows in the messagebox but I can't seem to get it to update the value on the main form.
Anytime I try to add a return value into FindCustomerControl_ItemHasBeenSelected, I get an error. It's like it hangs out in the user control and I can't leave it with a return value. So far, this is what I have:
In my main window:
public partial class TestForm : Form
{
public TestForm()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// one close button on the form
Close();
}
private void ShowSelectFromListWidget()
{
// show the user control
var uc = new FindCustomerControl();
uc.ItemHasBeenSelected += uc_ItemHasBeenSelected;
MakeUserControlPrimaryWindow(uc);
}
void uc_ItemHasBeenSelected(object sender,
FindCustomerControl.SelectedItemEventArgs e)
{
// once it has been selected, change a label on the screen to show the customer number
var value = e.SelectedChoice;
lblCustomer.Text = value;
}
}
In my user control:
public partial class FindCustomerControl : UserControl
{
public class SelectedItemEventArgs : EventArgs
{ public string SelectedChoice { get; set; } }
public event EventHandler<SelectedItemEventArgs> ItemHasBeenSelected;
public FindCustomerControl()
{ InitializeComponent();}
DataTable dt = new DataTable();
public void btnFind_Click(object sender, EventArgs e)
{ var dt = GetData();
dataGridView1.DataSource = dt; }
//Query database
public DataTable GetData()
{
UtilitiesClass ru = new UtilitiesClass();
string connectionString = ru.getConnectionString();
DataTable dt = new DataTable();
SqlConnection myConnection = new SqlConnection(connectionString);
myConnection.Open();
SqlCommand cmd = new SqlCommand("FindCustomer", myConnection);
cmd.Parameters.AddWithValue("#customer", txtCustomer.Text.Trim());
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter ta = new SqlDataAdapter(cmd);
ta.Fill(dt);
myConnection.Close();
return (dt);
}
private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
var handler = ItemHasBeenSelected;
string choice = dataGridView1[0, e.RowIndex].Value.ToString();
// this shows it
MessageBox.Show("Chosen: " + e.SelectedChoice);
if (handler != null) handler(this, new SelectedItemEventArgs { SelectedChoice = choice });
// I WOULD LIKE TO RETURN A VALUE HERE
}
}
It seems as though this should be common enough but, in spite of my hours of research and debugging, I have been unable to come up with a solution. I do know that uc.ItemHasBeenSelected += uc_ItemHasBeenSelected; in TestForm doesn't seem to ever get executed because I put a breakpoint there.
As I understood I guess you could use application current resources, where you can save any value you wish - in UWP it is something like this:
Application.Current.Resources["Name"] = customerNumber
Then you can cast this value to desired type:
(int)Application.Current.Resources["Name"]
Now you can use this value wherever you want.
Hope than helped in any way.
There is nothing wrong with the user class. It works fine. The problem is that the TestForm needs to start without the FindCustomerControl on it and instantiate the control within the program. It returns the value into the label or wherever else it needs to. Thanks very much to Brad Rem and this post: Return value from usercontrol after user action
public partial class TestForm : Form
{
public TestForm()
{
InitializeComponent();
ShowSelectFromListWidget();
}
private void button1_Click(object sender, EventArgs e)
{
Close();
}
private void ShowSelectFromListWidget()
{
var uc = new FindCustomerControl();
uc.ItemHasBeenSelected += uc_ItemHasBeenSelected;
this.MakeUserControlPrimaryWindow(uc);
}
void uc_ItemHasBeenSelected(object sender, FindCustomerControl.SelectedItemEventArgs e)
{
var value = e.SelectedChoice;
lblCustomer.Text = value;
lblMerchant.Focus();
//ClosePrimaryUserControl();
}
private void MakeUserControlPrimaryWindow(UserControl uc)
{
// my example just puts in in a panel, but for you
// put your special code here to handle your user control management
panel1.Controls.Add(uc);
}
private void ClosePrimaryUserControl()
{
// put your special code here to handle your user control management
panel1.Controls.Clear();
}
}
I have a code here but it didn't work, i want to refresh my combobox from another form by calling the method cmb_lod();
Form1 were my combobox created
public void cmb_load()
{
try
{
con.Open();
cmd = new SqlCommand("SELECT subjectCode FROM Subjects", con);
reader = cmd.ExecuteReader();
while (reader.Read())
{
cmbSubjects.Items.Add(reader[0].ToString());
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
con.Close();
}
Form2 where i want to refresh my combobox after adding value
private void btnRefresh_Click(object sender, EventArgs e)
{
frmManipulateClass mc = new frmManipulateClass();
mc.cmb_load();
}
The problem is that in the second form, you're creating a NEW instance of the first form and then refresh the combobox on it. This second instance has nothing to do with the first instance. What you need to do is to obtain a reference to the original first form and call the method on it. One way is in the first form:
public static frmManipulateClass Current {get; private set;}
public frmManipulateClass()
{
Current = this;
}
and then in the second form:
frmManipulateClass.Current.cmb_load();
This is only useful if you open just a single instance of the first form.
I have an event in my Form:
public void filterByType_TextChanged(object sender, EventArgs e)
{
dSearch = new D_Search(this);
dSearch.filterD(); }
which calls a function in another class. What I want to do is that I want to notice in my class which Textbox was altered and do something. So there are multiple functions like the one above and they all call the "filterD()" function in my DSearch class. I tried
if (sender == form1.filterByType_TextChanged)
{ sqlCmd = new SqlCommand("SELECT * FROM" } //SQL Statement
}
datTable = new DataTable();
sqlDatAdapter = new SqlDataAdapter(sqlCmd.CommandText,
connection);
sqlDatAdapter.Fill(datTable);
form1.setDataGrid = datTable;
but he can't find "sender" I also tried to create a new Button within the function in my Form and pass it but it doesn't seem to work.
try this -
In form 1
private void textBox1_TextChanged(object sender, EventArgs e)
{
var dSearch = new D_Search(this);
MessageBox.Show(dSearch.filterD(sender));
}
D_Search class
public class D_Search
{
Form1 frm = null;
public D_Search(Form1 frm1)
{
frm = frm1;
}
public string filterD(object sender)
{
string val = String.Empty;
if (sender == frm.textBox1)
{
val = (sender as TextBox).Text;
}
return val;
}
}
also if you want to access filterByType_TextChanged textbox in other class then change its modifier property to Internal
I'm trying to access an event in my main form by clicking a button (btnsearch_Click) and everytime I clicked it, it says 'object reference not set to an instance of an object'.
Here is my code:
USER CONTROL
namespace Purchase_Order
{
public partial class Search : UserControl
{
public event EventHandler btnSearchClicked;
public Search()
{
InitializeComponent();
}
private void btnsearch_Click(object sender, EventArgs e)
{
btnSearchClicked(sender, e);
}
}
}
MAIN FORM
namespace Purchase_Order
{
public partial class formMain : Form
{
public formMain()
{
InitializeComponent();
}
private void formMain_Load(object sender, EventArgs e)
{
Search searchbox = new Search();
searchbox.btnSearchClicked += new EventHandler(SearchClicked);
}
void SearchClicked(object sender, EventArgs e)
{
MySqlConnection con = new MySqlConnection(serverstring);
try
{
string query = "SELECT * FROM tblclassification WHERE INSTR(class_name, #search)";
MySqlCommand cmd = new MySqlCommand(query, con);
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
Search content = new Search();
cmd.Parameters.AddWithValue("#search", content.btnsearch.Text);
DataTable dt = new DataTable();
da.Fill(dt);
classification control = new classification();
control.dataGridView1.DataSource = dt;
control.dataGridView1.DataMember = dt.TableName;
panelMain.Controls.Clear();
panelMain.Controls.Add(control);
MessageBox.Show("OK");
}
catch (Exception)
{
throw;
}
finally
{
if (con.State == ConnectionState.Open)
{
con.Close();
}
}
}
You are creating a new instance of your user control in SearchClicked method and you are not registering the event against it.
Search content = new Search();
Also its better if you check whether any control has register your event before raising it like:
private void btnsearch_Click(object sender, EventArgs e)
{
if(btnSearchClicked != null)
btnSearchClicked(sender, e);
}
That means that you haven't got an instance of the type you want to use.
public event EventHandler btnSearchClicked; is just a reference for the "real" object you want to use.
It's like you trying to open a door of a house you only have a blueprint. This isn't really possible (at least not in our universe). You will first need to build the house and then try to enter it. Something like this is the case with your problem.
You will have to read a few tutorials about C#
Edit:
The thing about null is that there is nothing the reference you have is pointing too. If you haven't created anything then there isn't anything to reference...
Because you are trying to use something that doesn't exists (is null) you are getting an exception.
To try and expand a little on Habib's answer (I was going to post this as a comment but it's a little lengthy), you are first creating an instance of Search and registering the event in formMain_Load here:
private void formMain_Load(object sender, EventArgs e)
{
Search searchbox = new Search();
searchbox.btnSearchClicked += new EventHandler(SearchClicked);
}
This is all fine and dandy. However, in SearchClicked, you create a new instance of Search like so:
Search content = new Search();
This is a separate object to the one you created in formMain_Load and you never register the event to this object. It looks like what you want to do is share the Search instance from formMain_Load with the SearchClicked method. To do this, create a property in your codebehind:
public partial class formMain : Form
{
private Search _searchbox;
...
}
Then, in formMain_Load:
private void formMain_Load(object sender, EventArgs e)
{
_searchbox = new Search();
_searchbox.btnSearchClicked += new EventHandler(SearchClicked);
}
Now, you can reuse this object with the event registered in SearchClicked by changing this:
Search content = new Search();
To this:
Search content = _searchbox;
You should find that the exception goes away. Hopefully, this will have provided a little more insight and will help you to understand the cause of the error and how to circumvent it.
Share the Search instance from formMain_Load with the SearchClicked method
MAIN FORM
public partial class formMain : Form
{
private Search _searchbox;
...
private void formMain_Load(object sender, EventArgs e)
{
_searchbox = new Search();
_searchbox.btnSearchClicked += new EventHandler(SearchClicked);
}
void SearchClicked(object sender, EventArgs e)
{
Search content = _searchbox;
MySqlConnection con = new MySqlConnection(serverstring);
try
{
string query = "SELECT * FROM tblclassification WHERE INSTR(class_name, #search)";
MySqlCommand cmd = new MySqlCommand(query, con);
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
cmd.Parameters.AddWithValue("#search", content.btnsearch.Text);
DataTable dt = new DataTable();
da.Fill(dt);
classification control = new classification();
control.dataGridView1.DataSource = dt;
control.dataGridView1.DataMember = dt.TableName;
panelMain.Controls.Clear();
panelMain.Controls.Add(control);
MessageBox.Show("OK");
}
catch (Exception)
{
throw;
}
finally
{
if (con.State == ConnectionState.Open)
{
con.Close();
}
}
}
}
USER CONTROL
public partial class Search : UserControl
{
public event EventHandler btnSearchClicked;
public Search()
{
InitializeComponent();
}
private void btnsearch_Click(object sender, EventArgs e)
{
btnSearchClicked(sender, e);
}
}