I'm relatively new to C# and come a bit stuck.
I've got a Rich Textbox on a form, and I would like to update this from a different class to the Form itself.
I first tried
Form1.outputTextbox.AppendText(string);
but the text box was not accessible, made sense. So instead I tried to make a function. On Form1 I created the function
public void updateTextBox(string new_text)
{
outputTextBox.AppendText(new_text);
}
and in the class I used.
Form1.updateTextBox("apple");
The problem I'm having is the only way my class can see the function is if I make it the function static, but when I do that get an error "An object reference is required for the nonstatic field, method, or property 'member'"
Am I close or going to wrong way about this completely? Any help would be appricated.
Alternatively, you can do something like the following. This takes advantage of custom arguments and events.
namespace WindowsFormsApplication3
{
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;
public partial class Form1 : Form
{
TextBox textBox;
SomeClass someClass;
public Form1()
{
InitializeComponent();
Initialize();
BindComponents();
}
private void BindComponents()
{
//EventHandlers
this.Load += new EventHandler(Form1_Load);
this.someClass.TextUpdatedEvent += new EventHandler(someClass_TextUpdatedEvent);
}
void someClass_TextUpdatedEvent(object sender, EventArgs e)
{
this.textBox.Text = (e as FormArgs).Text;
}
private void Initialize()
{
this.textBox = new TextBox();
this.someClass = new SomeClass();
}
void Form1_Load(object sender, EventArgs e)
{
this.Controls.Add(textBox);
}
}
public class SomeClass
{
public event EventHandler TextUpdatedEvent = delegate { };
public void UpdateText(string text)
{
if (TextUpdatedEvent != null)
{
TextUpdatedEvent(this, new FormArgs() { Text = text });
}
}
}
public class FormArgs : EventArgs
{
public string Text { get; set; }
}
}
If you do it this way, you can update the form text like this:
someClass.UpdateText("changing the text on the form");
You are trying to access the function from the class instead of the object.
Use
Form1 myForm = new Form1();
...
myForm.updateTextBox("whatever");
Also be aware of thread issues here. What triggers the outside code? Is it another ui action, then all is well. Does it come from another thread, then you´ll have to handle this.
Pass Form1 instance to the other class via constructor or property. Then you can access outputTextbox from the other class.
public class OtherClass
{
private Form1 form1;
public OtherClass(Form1 form1)
{
this.form1 = form1;
}
private void ChangeText()
{
form1.outputTextBox.AppendText("hello world");
}
}
Instantiate OtherClass from Form1.cs and pass its instance.
In Form1.cs:
OtherClass obj = new OtherClass(this);
I know it is very late, but maybe someone need the solution...
you can access to all controller from another form without create object by pass it as parameter to constructor...
for Example
public partial class Form2 : Form
{
MainForm mainForm;
public Form2(MainForm mainForm)
{
InitializeComponent();
this.mainForm = mainForm;
txtRecive00.TextChanged += new EventHandler(txtRecive8changed);
}
void txtRecive8changed(object sender, EventArgs e)
{
mainForm.txtRecive1.Text += txtRecive00.Text;
}
in my case I can update the text in mainForm.txtRecive1.Text from Form2...
and in MineForm we creat object from Form2 like that:
Form2 f2 = new FormMeasure(this);
for more Info show this short video https://www.youtube.com/watch?v=CdH8z_JNi_U
Related
Maybe you can help me with my problem.
My Class "Form1" calls the method setButtons();
but setButtons() ist not at Class "Form1", its in Class "Class1".
setButtons() in "Class1" does not recognice Button1 from Form1.
How do I let it know that Button1 exists in Form1 and I want the method to work on the Button1 from "Form1"? Class1 has already a using directory to Form1 and Form1 has one to Class1.
//this does not work
public static void setbuttons()
{
Form1.Button1.Location = new Point(40, 40);
}
I found out that if you declare a control public in the designer file like so
public Button button1;
Then you can access it from another class on the condition that you get the form object, for example as a extension
static class AnotherClass
{
public static void setButtons(this Form1 form)
{
form.button1.Text = "Hello";
}
}
A better way to change the properties of a button, in terms of design and code management, would be to make a method in your form that does it.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
...
}
public void ChangeButtonTextMethod(string text)
{
button1.Text = text;
}
}
Consider using an event where the method in Class1 passes a Point to the calling form which listens for the event, in this case SetButtons.
public class Class1
{
public delegate void OnSetLocation(Point point);
public static event OnSetLocation SetButtonLocation;
public static void SetButtons()
{
SetButtonLocation!(new Point(40, 40));
}
}
In the form subscribe to SetButtonLocation, invoke the method SetButtons which passes a Point to the caller in Form1 and in turn sets the button Location.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Class1.SetButtonLocation += OnSetButtonLocation;
Class1.SetButtons();
Class1.SetButtonLocation -= OnSetButtonLocation;
}
private void OnSetButtonLocation(Point point)
{
button1.Location = point;
}
}
Using this approach is better than changing the modifers of form to public as mentioned already.
I want to expose the Text property of a textbox on Form1 to Form2 so Form2 can set the text in the textbox on Form1. I've read how to do it but it doesn't work so I must be doing something wrong.
Here's the code for Form1 including the declaration of the public property (TextInputText is the property, txtInput is the textbox):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public string TextInputText
{
get => txtInput.Text;
set => txtInput.Text = value;
}
public Form1()
{
InitializeComponent();
}
private void txtInput_KeyDown(object sender, KeyEventArgs e)
{
// If enter is pressed clear the textbox, but update() the history first
if (e.KeyCode == Keys.Enter)
{
TextHistory.Update(txtInput.Text);
txtInput.Text = "";
}
}
private void HistoryButton_Click(object sender, EventArgs e)
{
Form2 HistoryForm = new Form2();
HistoryForm.Show();
}
}
}
The problem is Form2 still can't see the property, or I don't know how to access it, what am I doing wrong?
Either inject Form2 with a reference to Form1 when you create it:
private void HistoryButton_Click(object sender, EventArgs e)
{
Form2 HistoryForm = new Form2(this);
HistoryForm.Show();
}
This requires you to define a custom constructor in Form2 that accepts a Form1 reference. You can then use this reference to access the property:
private readonly Form1 _form1;
public Form2(Form1 form1)
{
InitializeComponent();
_form1 = form1;
string text = _form1.TextInputText;
}
Another approach is to use the Application.OpenForms property to get a reference to Form1 in Form2:
var form1 = Application.OpenForms.OfType<Form1>().FirstOrDefault();
string text = form1.TextInputText;
You do not give Form2 a reference to the Form1 instance:
Form2 HistoryForm = new Form2();
How could you access a Instance Function, Property or Value, without a Instance? A static property would not make sense. So the most likely option is to give Form2 a constructor that takes a Form1 reference as Argument. Store that reference somewhere in Form2. Then call the constructor like this:
Form2 HistoryForm = new Form2(this);
i have a main form with a function that changes the text of a text box thats on the main form, the code is below:
main form function:
public void consoleLog(string message)
{
txtConsoleLog.Text += Environment.NewLine;
txtConsoleLog.Text += message;
txtConsoleLog.SelectionStart = txtConsoleLog.TextLength;
txtConsoleLog.ScrollToCaret();
txtConsoleLog.Refresh();
}
So now i open a new form called frm connect when i click a button like this:
private void connectToolStripMenuItem_Click(object sender, EventArgs e)
{
Form frmConnect = new FrmConnect(this);
frmConnect.Show();
}
this is the frmConnect below
public partial class FrmConnect : Form
{
private Form mainForm;
public FrmConnect(Form frmMain)
{
this.mainForm = frmMain;
InitializeComponent();
}
private void btnConnect_Click(object sender, EventArgs e)
{
FrmMain.Connected = true;
mainForm.consoleLog("Connected");
}
}
So when i click a button i want to call the function but its saying it doesnt contain a definition for it, also im trying to change the 'Connected' variable thats on the main form which works by just referencing the FrmMain but am i able to do that using mainForm.Connected = true?
If i change the function to public static, it will work by referencing FrmMain but then i get errors with the txtConsoleLog as i cant reference an object in a non static method or something like that, any help is appriciated
When you pass the form into your constructor, and store it as the private member variable, in both places you declare it of the base type Form. In order to use a method on the type that you defined, your parameter and variable should be of type FrmMain.
public partial class FrmConnect : Form
{
private FrmMain mainForm;
public FrmConnect(FrmMain frmMain)
{
this.mainForm = frmMain;
InitializeComponent();
}
private void btnConnect_Click(object sender, EventArgs e)
{
FrmMain.Connected = true;
mainForm.consoleLog("Connected");
}
}
You should change
private Form mainForm;
public FrmConnect(Form frmMain)
{
To
private FrmMain mainForm;
public FrmConnect(FrmMain frmMain)
{
which will later give you access to all of the public properties on FrmMain in your other methods in the FrmConnect class.
i need your help.
I have two forms, Form1 and Form2. In Form1 i have a checkBox1 and in Form2 I have a checkBox2. All i want is the value of checkBox1 tranfering automatically in checkBox2.
Thanks in advance
First of all, in a multi-form application, form-form direct contact should not be permitted. However, I can think of a way which I present here considering yours is an exceptional scenario. So the method might violate usual best practices.
Here is the method
Make your checkboxes in your forms as Public. You can do that by clicking on the CheckBox in the design mode and then selecting Public under Modifiers in Properties window. This step makes your checkbox accessible from outside your form's instance.
Write the following code in CheckedChanged event of CheckBox in Form1.
((Form2)(Application.openForms["Form2"])).checkBox1.Checked = this.checkBox1.Checked;
However, I strongly recommend revisiting your strategy based on your application need.
On Form1:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
Form2 a = new Form2();
a.c = checkBox1.Checked;
a.ShowDialog();
}
}
On Form2:
public partial class Form2 : Form
{
public bool c;
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
checkBox1.Checked = c;
}
}
All instances of Form2 within an MDI parent will reflect any change to the CustomCheckBox control Checked property placed on the Form. Of course, this would be true of when placing the CustomCheckBox on any MDI child form, just set up the proper events like Form2.
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;
namespace WindowsFormsApplication1 {
public partial class Form2 : Form {
public Form2() {
InitializeComponent();
CustomCheckBox.CheckChanged += (object sender, EventArgs e) => {
if (sender != m_customCheckBox) { m_customCheckBox.Checked = CustomCheckBox.GetCheck(); }
};
FormClosed += (object _sender, FormClosedEventArgs _e) => {
CustomCheckBox.CheckChanged -= (object __sender, EventArgs __e) => { };
};
}
};
};
////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1 {
public class CustomCheckBox : CheckBox {
static private bool? m_checked = null;
static private object m_synchRoot = new object();
static public event EventHandler CheckChanged;
public CustomCheckBox() {
if (HasCheckValue) {
// Do this BEFORE we set up the CheckChanged event so that
// we do not needlessly kick off the CustomCheckBox.CheckChanged
// event for any other existing CustomCheckBoxes (as they already
// have their Checked property properly set)...
Checked = CustomCheckBox.GetCheck();
}
this.CheckedChanged += new EventHandler(OnCheckedChanged);
}
protected void OnCheckedChanged(object sender, EventArgs e) {
if (CustomCheckBox.HasCheckValue && this.Checked == CustomCheckBox.GetCheck()) {
return;
} else {
CustomCheckBox.SetCheck(this.Checked);
if (CustomCheckBox.CheckChanged != null) {
CustomCheckBox.CheckChanged(sender, e);
}
}
}
static public bool HasCheckValue {
get {
lock (m_synchRoot) {
return m_checked.HasValue;
}
}
}
static public bool GetCheck() {
lock (m_synchRoot) {
return m_checked.Value;
}
}
static private void SetCheck(bool _check) {
lock (m_synchRoot) {
m_checked = _check;
}
}
};
};
I have form with button and checkbox. if i hit button static void is called which call non static void which shows messagebox with the checkbox.checked.toString()
The problem is if i change the checkbox value it always shows false
Code is
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
public void y()
{
MessageBox.Show(checkBox1.Checked.ToString());
}
static void x()
{
Form1 f = new Form1();
f.y();
}
private void button1_Click(object sender, EventArgs e)
{
x();
}
}
}
Method x instantiates a new form. The check box on the new form will also be new (created with the form) and will have a default value of false.
What exactly are you trying to do? Why create a new form when the button is pressed? If you really want to do this then you need to set the new form's check box state after you call Form f = new Form1();
I guess you have probably came from a Visual Basic background like I do.
In C#, form are just instances of a Form class, they does not have special status like in the days of VB6.
When you call new Form1() you are basically creating a new form not accessing the same form. As anyone form can have multiple instances because it really is just a C# class underneath.
You can fix this by having the x() method takes the current form as a parameter
static void x(Form1 theForm)
{
theForm.y();
}
private void button1_Click(object sender, EventArgs e)
{
x(this);
}
The this parameter inside a form class points to the form instance itself.
You should now gets the correct value instead of the default value when the form is being created.
I suppose you have a need for x() to be static, no? But if that isn't the case, removing static from x() might be a better solution.
void x()
{
this.y();
// or you can just omit the this qualifier and call just y();
}
Try
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
public void y()
{
MessageBox.Show(checkBox1.Checked.ToString());
}
static void x(Form f)
{
f.y();
}
private void button1_Click(object sender, EventArgs e)
{
x(this);
}
}
It's because your instantiating a new Form1 inside x(), try passing 'this' to the x method as a parameter.
You're creating a new Form1 instance. Why are you doing that? When you create a new form, a new checkbox is created as well. The checkbox on the form looks like is set to false (not checked) by default, therefore, every time you create a new instance of the form, it comes up as false.
The checkbox1 in y() is on a completely different Form1 - the one you created in x. Simply get rid of x() and it should work:
private void button1_Click(object sender, EventArgs e)
{
y(); // not x();
}
your issues are in the x() method, what you're doing there is actually making an entirely new form and checking that forms check box, which would obviously be instantiating as false.
Rather then calling x() you should call y().
Or, alternatively, put the messagebox.show in the buttonclick method itself.
If you need to access some form instance from static method, you need to save somewhere a reference to that form.
class Program
{
public static Form thatForm;
public static void Main(string[] args)
{
MyForm form = new MyForm();
thatForm = form;
Application.Run(form);
}
}
class MyForm : Form
{
void Foo()
{
Program.thatForm.somethingPublic();
}
}