So im trying to execute a method from a Timer the problem is that everytime i call the method and pass a string as argument, automatically the string is set to NULL and that's weird, is there a fix or something, here is some code if you wish to look at it
private void timer1_Tick(object sender, EventArgs e)
{
int currentHour = FixTime(DateTime.Now.ToString("hh tt"));
int currentMinute = FixTime(DateTime.Now.ToString("mm tt"));
int currentSeconds = FixTime(DateTime.Now.ToString("ss tt"));
string currentTT = DateTime.Now.ToString("tt");
int userHour = Settings.Default.hour;
int userMinute = Settings.Default.minutes;
int userSeconds = Settings.Default.seconds;
string userTT = Settings.Default.TT;
if (currentHour == userHour && currentMinute == userMinute &&
currentSeconds == userSeconds && currentTT == userTT)
{
MakeThePost(postTextBox.Text); // the postTextBox.Text field automatically is set to null
}
}
private void MakeThePost(string data)
{
string text = data;
if (!String.IsNullOrEmpty(text))
{
fb.Post("me/feed", new { message = text });
}
else
MessageBox.Show("Nothing to post on facebook", "Field is empty",MessageBoxButtons.OK, MessageBoxIcon.Error);
}
UPDATE: So aparently the problem isnt in the timer or even in the MakeThePost the real problem is in another form iam trying to display, when its displayed the constructor makes a new Form1 object, why i make this?, because i want to have access to the controls in the main form, but when i execute the Form1 constructor to make a new object, the Form1 postTextBox control stop updating its Text property, so is there another way to access main Form controls without initializing an object?
The posted code doesn't seem to contain anything that would cause the postTextBox.Text property to become null.
There has to be something else in your application that nulls that property. Make sure Data Binding is not silently setting this to null.
Insert breakpoints both on the line calling MakeThePost, and on the first line of MakeThePost, then run the application.
See if the property is null only before the call, or both before and inside the method.
EDIT:
According to your latest edits, it seems you're creating a new Form1 instance, whereas you should probably pass a reference to the existing one when instantiating Form2
Add a Form2 constructor that takes a Form1 object as parameter:
public partial class Form2 : Form
{
private Form1 otherForm;
public Form2()
{
InitializeComponent();
}
public Form2(Form1 frm) : this()
{
otherForm = frm;
}
//Other methods and properties of Form2
}
Then create a new instance of Form2:
Form2 secondForm = new Form2(form1Instance);
Now, inside the Form2 instance, you have the otherForm reference, which will allow you to call public members of the Form1 instance. You might have to change the access modifier on some Form1 members to make them public.
Related
I have two windows forms. One of them has a variable.
In that form, I have created a get method:
public string getUSERID
{
get
{
return userID;
}
}
In the second form, I am attempting to use this method like so:
private void Form2_Load(object sender, EventArgs e)
{
UserID = Form1.getUSERID();
}
For reasons I do not understand, the second form does not recognize getUSERID as a viable method for Form1, and I have no idea why.
I've searched the forums, and the answer I keep finding is exactly what I did: build a "get/set" method, and activate it with FormX.get/set.
Is there anything I'm doing wrong here?
EDIT: To calrify - Form 1 is the first form that opens. While it's open, I am opening Form 2 from within form 1 like so:
Form Form2 = new Form2();
Form2.Show();
conn.Close();
Hide();
(The connection is because form 1 used a connection until now).
Now, since I'm opening Form2 before I hide Form1, I thought that the data in Form1 would still be available during FormLoad of Form2, so I can extract the variable from it, then close Form1.
After your clarification, what would i do is this. In Form2 create a parameter constructor,like this:
string form1UserId="";
public Form2(string UserID)
{
InitializeComponent();
this.form1UserId=UserID;
}
And then, from Form1 you just have to do this:
Form2 frm2 = new Form2(userID);
frm2.Show();
conn.Close();
Hide();
Hope this helps.
Two things are wrong here. First is that you define getUSERID as a property but are trying to access it like a method. Second is that you define getUSERID as a non-static method but are trying to use it as a static method. To fix the first problem, rename getUSERID to USERID in your property declaration and access it without the parentheses (i.e. someForm.USERID). To fix the second problem, you'll need to access the USERID property from an instance of Form1, not as a static member on the class Form1, like so:
Form2.cs
private Form1 _f1;
public Form2(Form1 f1): Form2()
{
_f1 = f1;
}
// ...
private void Form2_Load(object sender, EventArgs e)
{
UserID = _f1.USERID;
}
You've defined it as a property, not a method, so no () is needed.
Also, to access it without creating an instance (new Form1()), it would have to be static.
the second form does not recognize getUSERID as a viable method
That's because it isn't a method, it's a property. Omit the parens, and you'll find it works.
Here in your case getUSERID is a read only property of string type, which will return the userID of that class. And one more thing to be noticed is that the property is not defined as static so an object reference is required to access the property value; so the signature of the page load will be
private void Form2_Load(object sender, EventArgs e)
{
Form1 newForm1= new Form1();
UserID = newForm1.getUSERID; // UserID will be same as that of Form1's userID
}
You can define the property as static inn-order to avoid creating instance. if so you can access the same property from any other forms without creating instance of the form1. So the definition of the Class Form1 will be like the following
public class Form1
{
private static string _UserId = "Some value";
public static string UserId
{
get { return _UserId; }
}
// rest of statements
}
So that you can access the UserId from any other forms by using Form1.UserId no need to create an instance of the Form1
public **static** string getUSERID
{
get
{
return userID;
}
}
private void Form2_Load(object sender, EventArgs e)
{
UserID = Form1.getUSERID(); // If the property has static it's possible to write like this.
}
(or)
public string getUSERID
{
get
{
return userID;
}
}
private void Form2_Load(object sender, EventArgs e)
{
Form1 f= new Form1();
UserID = f.getUSERID();
}
Just give the second form the variable when you open it, like so:
SecondForm f2 = new SecondForm(YourVariable);
f2.Show();
//Global Variable
var SaveVariableFromForm1;
protected override void OnCreate(var YourVariable)
{
//Imagine this is the Form2 OnCreate();
SaveVariableFromForm1 = YourVariable;
}
And catch the variable on the 2ยบ Form's OnCreate Method save it in a Global Variable and use it were ever you feel like it, hope this helps.
I have a main Windows Form (From1) which has a TextBox in it. I've also created another Windows Form (FindReplaceForm) which I'm going to use for implementing a form of find and replace dialog. I need to fully access all the properties and methods of my textbox in From1 from FindReplaceForm window.
Although I set the Modifiers property of my TextBox to Public, in FindReplaceForm window I can't access the text in it.
You can access the the owner form in the child using:
((Form1)Owner).textBox1.Text = "blah";
Assuming you have called your the child form using:
Form2 form = new Form2();
form.Show(this);
You need to pass a reference to the control or the form to your constructor so that you can reference the instance of the class. Add an argument of the same type as the calling form to the constructor:
private Form1 calling_form;
public FindReplaceForm (Form1 calling_form)
{
this.InitializeComponent()
this.calling_form = calling_form;
}
Then in your button call you can say:
calling_form.TextBox_value_text.SelectedText = "";
In your code, Form1 is a CLASS, not a variable. When you show your FindReplaceForm you should specify the Owner (just use this).
Now you can the Owner property on FindReplaceForm to get access to Form1.
Showing FindReplaceForm:
FindReplaceForm.Show(this);
In your button click event:
void Buttton1_Click(object sender, EventArgs e)
{
((Form1)this.Owner).TextBox_value_text.SelectedText = "";
}
Even if you set the textbox access modifier back to private, you can simply pass a reference to the textbox in the second form's constructor, thus enabling the second form to manipulate any property of the textbox:
first form:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 frm = new Form2(this.textBox1);
frm.Show();
}
}
second form:
public partial class Form2 : Form
{
private TextBox _OwnerTextBox;
public Form2(TextBox ownerTextBox)
{
InitializeComponent();
_OwnerTextBox = ownerTextBox;
this.textBox1.Text = _OwnerTextBox.Text;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
_OwnerTextBox.Text = this.textBox1.Text;
}
}
In your FindReplaceForm.button1_Click function you want to control an object of class Form1. The error in your code explains that you don't call a function of an object of class Form1, but a function of class Form1 itself. The latter can only be done on static functions
You describe that you have an existing Form1 object and that your FindReplaceForm needs to change Form1 by calling functions in Form1. Probably there might be more than 1 Form1 object. Therefor your FindReplaceForm instance somehow needs to know which Form1 object it needs to control. Someone needs to tell this to your FindReplaceForm. This is usually done using the constructor of the FindReplaceForm or using a property.
public class FindReplaceForm
{
private Form1 formToControl = null;
public FindReplaceForm(Form1 formToControl)
{
this.formToControl = formToControl;
}
private void OnButton1_Click(...)
{
this.formToControl.TextBox_Value_Text.SelectedText = ...
}
Another method would be not to put the formToControl in the constructor, but as a property that you can set separately. Both methods have their advantages:
via constructor: your FindReplaceForm knows for sure there is alway a formToControl. The only place you have to check if formToControl really exists is in the constructor.
Using a default constructor with a separate FormToControl property may cause run time errors if people forget to set the FormToControl.
If you have a lot of properties, or some properties may have default values, or may be changed later, then the property method is more flexible.
I have an TextBox named pass in Form1 that I need to get the value of in form2. I tried this:
public partial class Form1 : Form {
public string GetPass() {
return pass.Text;
}
}
public partial class form2 : Form {
//...
MessageBox.Show(new Form1().GetPass());
}
The above code returns an empty string, why?
You are not showing your actual code as evidenced by the syntax errors etc. - the only logical explanation for your problem is that you are not passing the reference to Form1 correctly to Form2, but create a new form instead - that new form would have the empty textbox.
To further help you, please show how you pass the reference to your Form1 in your actual code.
Edit:
Is see your edit now and above is exactly the problem. You have to pass a Form1 instance to form2 instead of creating a new one, i.e.:
public partial class form2 : Form
{
private Form1 form1;
public form2(Form1 otherForm)
{
form1 = otherForm;
}
public void Foo()
{
MessageBox.Show(form1.GetPass());
}
}
Define one string variable as Public in declaration section
for ex. we have a form with name "frmOne"
public string strVar = string.Empty;
Now, assign the value of TextBox of "frmOne" to that variable from where you are getting the value of Textbox.
for ex.
strVar = Textbox1.Text.ToString();
Now in another form say "frmTwo", you will get access the value of that textbox of "frmOne" something like that (where you want to get the value) :
frmOne frm = new frmOne();
string strValue = frm.strVar;
So, finally strValue local variable of frmTwo contains the value of Textbox of frmOne.
You are creating a NEW form1 where the textbox is likely to be blank, and calling GetPass() on that empty form. You need an instance of the already-opened form1 where the textbox might have a value.
Because you are creating a new instance of Form1 each time you call GetPass().
You need to get the instance of the opened form1 one way or another, and call GetPass on it:
form1.GetPass();
If there is no specifics on the order of creation of form1 and form2, you can use the following to get the instance of form1:
foreach (Form openedForm in Application.OpenForms) {
if (openedForm.GetType() == Form1) {
MessageBox.Show(openedForm.GetPass());
}
}
It's returning empty because you're creating a new instance of the form. Assuming that Form1 is already open somewhere, you need to retrieve the existing instance of Form1 and pull the value from there.
hi you can write this :
public partial class Form1: Form
{
public Form1()
{
InitializeComponent();
}
internal Form2 F2=new form2();
private void CommandBarButton1_Click(object sender, EventArgs e)
{
MessageBox.Show(f2.TextBox1.Text);
}
}
I have done some research on this question before deciding to ask it. I just could not find anything that helped me.
I am writing an application in C# for the compact framework 2.0.
I need to take a data object instantiated on form1 and pass that object a form2. Work on the data object in form2 and then pass that data back to form1 so it can be saved.
I understand that a form is just an object an I also understand that objects are past by reference and not by value. I also understand the difference between the two types. I just cannot make it work for some reason.
What is the best, and cleanest, way in code to achieve this?
What you need to do is create a second constructor to your second form that accepts an object as a parameter... for all I care, it could be the entire Form1 object instance, then you can get whatever you want from it. Preserve this object in your second form and modify it as needed there. Upon completion of your second form, your first form will have that data and you can do whatever "refreshing" once the second form closes.
public partial class YourSecondForm : Form
{
object PreserveFromFirstForm;
public YourSecondForm()
{
... its default Constructor...
}
public YourSecondForm( object ParmFromFirstForm ) : this()
{
this.PreserveFromFirstForm = ParmFromFirstForm;
}
private void YourSecondFormMethodToManipulate()
{
// you would obviously have to type-cast the object as needed
// but could manipulate whatever you needed for the duration of the second form.
this.PreserveFromFirstForm.Whatever = "something";
}
}
I've always liked the eventing model for this. This way your forms don't need to know about anyone else. You can setup an event like the following in some kind of EventHandler class that is used by both forms.
public delegate void SavingObjectHandler(MyObject obj);
public event SavingObjectHandler SavingObjectEvent;
public void SavingObject(MyObject obj)
{
if (SavingObjectEvent != null) SavingObjectEvent(obj);
}
then your one form can call the SavingObject even handler and the other can subscribe to the SavingObjectEvent. When the first form triggers the event the second form will be notified do the processing that it needs and the object will then be available to the first form again after the manipulation.
Something like this where the ObservableForm is a base class and contains the ChangeEvent for further flexability:
public class FormMain : Form
{
private ObServableForm childForm = null;
public FormMain () {
this.childForm = new ObservableFormConcreateA(this);
this.childForm.ChangeEvent += (sender, e) => Application.DoEvents();
}
public void Present() {
this.childForm.Show();
}
}
public class ObservableFormConcreateA ObServableForm
{
private Form workItemForm = null;
private delegate void FormChangedHandler(object source, EventArgs args);
//ToDo: this should go in the superclass
public event FormChangedHandler ChangeEvent;
public FormChild(ObServableFormworkItem) {
this.workItemForm = workItem;
}
public void OnUserActionHandler(object sender, EventArgs e) {
this.formItemForm.Property = this.txtBoxWhateverValue.Text;
if(ChangeEvent != null)
ChangeEvent(this, //create your args to specify which control/data changes);
}
}
I've got an interesting solution for you, involving closure. In the constructor for Form2, require an Action<TypeOfThing> object, and whenever you need to return the data to Form1, call that Action and pass the data into it. For example:
class Form1 : Form
{
private void SomeFunction()
{
TypeOfData data;
Form2 form2 = new Form2((d) => { data = d; });
form2.ShowDialog() // or whatever you do with form2
// After you've definitely got your data object from Form2
DoStuff(data);
}
}
class Form2 : Form
{
private Action<TypeOfData> returnData;
private TypeOfData data;
public Form2(Action<TypeOfData> r)
{
returnData = r;
}
private void SomeFunction()
{
// Whenever it comes time to return the data you've collected
returnData(data);
}
}
I've used this implementation in the following circumstance: I had to request a password from the user, and I wanted to do so with a dialog box, so I designed my dialog box with a textbox where the user could type their password, and OK and Cancel buttons. On FormClosing, I'd return the string (their password) by calling the Action, and I would only ever use that Form as a dialog, so I could be sure the variable would be assigned to a string by the time the code continued in Form1. This way I didn't have to make a property for Password, which wouldn't have made sense because the password was only a temporarily necessary piece of data.
I am trying to access a button on my default created form from a different thread in the same application. However, I get the error
An object reference is required for the non-static field, method, or property 'BElite.Form1.testButton1'
where Form1 is the default form created and testButton1 is the test button that I want to change the text of from my thread.
I understand that I somehow need to get a reference to the Form1 object... but i have no idea how!
Please help.
You are referencing testButton1 like it was a static field instead of an instance field. You need to be able to access the instance of the form. You can do this like this:
public partial class Form1 : Form
{
public static Form1 Instance { get; private set; }
public Form1()
{
InitializeComponent();
if (Instance != null)
throw new Exception("Only one instance of Form1 is allowed");
Instance = this;
FormClosed += new FormClosedEventHandler(Form1_FormClosed);
}
void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
Instance = null;
}
public Button TestButton1 { get { return testButton1; } }
}
Because controls on the form are protected by default, you have to make the button accessible. You do this using the TestButton1 property.
Now you can access the textbox using BElite.Form1.Instance.TestButton1.
Two notes:
This only works if you always have a single Form1, for example when Form1 is the main form of your application;
Please note that accessing these controls from a different thread must be done using Control.Invoke() or Control.BeginInvoke(). See the documentation on these methods on why and how.
You can access the button using BeginInvoke() with the following sample:
Form1.Instance.BeginInvoke(new Action(() =>
{
Form1.Instance.TestButton1.Text = "My new text";
}));
Everything in the block ({ ... }) is safe.