C# Adding controls to a form from another class - c#

Every time I create a new instance of Player I want to do the following code
private void button1_Click(object sender, EventArgs e)
{
Player Player1 = new Player();
}
Player class
{
public Player()
{
Form1.AddControls(someControl)
}
}
I can't seem to do anything to do with form1 e.g. textbox1.text = "Test". I assume this is a scope issue but I can't find an answer on the internet. Does anyone know how I can access + add controls to my form1 through a class?
Thank you for your time.

It's not entirely clear what you're trying to do. It sounds like you want to add controls from the Player class into the form that you're calling from like this:
public class Form1 : Form
{
public void SomeMethod()
{
Player player1 = new Player(this);
}
}
public class Player()
{
public Player(Form form)
{
Textbox tb = new Textbox();
form.Controls.Add(tb);
}
}

Related

How do I access a usercontrol instance in another usercontrol instance?

I have two UserControls: Player and Playlist.
Player.cs
namespace Music_Player
{
public partial class Player : UserControl
{
public int currentSongIndex = 0;
public WindowsMediaPlayer player = new WindowsMediaPlayer();
public Player()
{
InitializeComponent();
player.settings.autoStart = false;
}
private void playButton_Click(object sender, EventArgs e)
{
if (playButton.Text == "Play")
{
Play();
}
else
{
Pause();
}
}
public void Play()
{
if (CheckSongs()) { return; }
playButton.Text = "Pause";
player.controls.play();
}
...
Playlist.cs
namespace Music_Player
{
public partial class Playlist : UserControl
{
public Playlist()
{
InitializeComponent();
}
private void playlistTitle_Click(object sender, EventArgs e)
{
player.Play(); // THIS IS WHERE I WANT TO USE THE player INSTANCE OF Player()
}
...
The UserControls are both children of another UC which is in my Form.
How can I use the player which is an instance of Player() inside Playlist?
Suppose you have added a player1 and a playList1 to the form.
To call the method in another UserControl, you can define a property in Form.cs to access the player1 instance.
public Player PlayerInstance
{
get { return player1; }
}
Then you can call Player.Play() in Playlist.cs via the code as followed.
private void playlistTitle_Click(object sender, EventArgs e)
{
Form1 form1 = (Form1)this.FindForm();
form1.PlayerInstance.Play();
}
You probably want to handle events in the form the controls are in, not within the control itself. The form would have a reference to both controls and likely whatever they are controlling. That's where things should be connected.

Windows Forms, accessing picturebox from class in main form

I'm making a game where I want to make things fall down and the player should try to catch it.
Currently, my items which are falling are drawn and made in a class separated from the main form, so when I try to access them from the main form where I control the gravitation.I can't seem to find the picturebox (picCoin).
Could you please take a look at my code and come with some solution?
This is the class were i create Coins
class Coin
{
private PictureBox picCoin = new PictureBox();
public Coin()
{
picCoin.BackColor = Color.Transparent;
picCoin.ImageLocation = #"C:\Users\sebfre1104\source\repos\SPEL\SPEL\Resources\hamburger.png";
picCoin.Width = 100;
picCoin.Height = 100;
picCoin.SizeMode = PictureBoxSizeMode.StretchImage;
}
public void DrawTo(Form f)
{
f.Controls.Add(picCoin);
}
public Rectangle getBounds()
{
return picCoin.Bounds;
}
public void setposition(int x, int y)
{
picCoin.Location = new Point(x, y);
}
}
i want to reach this picCoin in my main form so i can add gravity in private void TimerGravitation_Tick(object sender, EventArgs e)
public partial class Form1 : Form
{
bool IsJumping = false;
List<Coin> clist = new List<Coin>();
int poƤng = 0;
public Form1()
{
InitializeComponent();
}
private void TimerGravitation_Tick(object sender, EventArgs e)
{
if(!picSpelare.Bounds.IntersectsWith(picMark.Bounds) && IsJumping==false)
{
picSpelare.Top += 10;
}
}
I would be very grateful with any tips as this is my final project in class.
i dont know if i understanded question correctly but make picCoin public
make
private PictureBox picCoin = new PictureBox();
to
public PictureBox picCoin = new PictureBox();
At first, you should follow Umut Arpat's answer (turn picCoin from private to public).
Then you should initialize the Coin class in Form1 constructor like this:
private Coin _coin;
public Form1()
{
InitializeComponent();
_coin = new Coin();
}
And then you should add picture box from Coin class to list of Form1 controls like this:
this.Controls.Add(_coin.picCoin)
You can do that in Form1 constructor too.
Don't add PictureBox to Controls of the form from the Coin class (method DrawTo()).
class Coin
{
private PictureBox picCoin = new PictureBox();
public PictureBox Box {
get { return picCoin};
set { picCoin = value};
}
....
}
To use/access the box:
clist[i].Box // This is what you want

Accessing MainForm from another class file

I have this MainForm class:
namespace homework_001{
public partial class MainForm : Form
{
public MainForm()
{InitializeComponent();}
public string Change
{
get{ return label.Text;}
set{ label.Text = value;}
}
void ButtonClick(object sender, EventArgs e)
{
Test a = new Test();
a.changer();
}
}}
And I have this class:
namespace homework_001{
public class Test
{
private MainForm form = new MainForm ();
public void changer(){
form.Change = "qqqqq!";
}
}}
Desired workflow is to change the label/text on button press.
It compiles, but nothing happens after I press the button.
What might be the issue?
What is happening is that the form you are showing is not the same as the one inside the class Test.
To make things work you should pass the form to the class Test in this way:
public class Test
{
private MainForm form;
public Test(MainForm f)
{
this.form=f;
}
public void changer(){
form.Change = "qqqqq!";
}
}}
and in your main form you do this:
public partial class MainForm : Form
{
public MainForm()
{InitializeComponent();}
public string Change
{
get{ return label.Text;}
set{ label.Text = value;}
}
void ButtonClick(object sender, EventArgs e)
{
Test a = new Test(this);
a.changer();
}
}}
done create a new object of the main form.. Instead. make the string Change public and static
and change it from test class like Mainform.Change="some text";
You're creating another MainForm object, different from the one that's actually displayed on the screen. To work on the same object you need to pass it to the Test class, like this:
Test a = new Test(this); // "this" is the MainForm object you want to work with
a.changer();
This will give Test class a reference to your MainForm object.
Now, you need to create a constructor in Test with one argument, and store the received reference to your form object in Test's private MainForm form field. You shouldn't have any trouble doing that.
change you code below:
void ButtonClick(object sender, EventArgs e)
{
Test a = new Test();
a.changer(ref this);
}
you pass the form object to function by refrence and changed that
public class Test
{
public void changer(ref MainForm form){
form.Change = "qqqqq!";
}
}
refer this link Passing Reference-Type Parameters (C# Programming Guide)

No errors, label seems like it should change to the indicated text but its not

Can anybody tell me why this is doing nothing? pcNameLabel.Text is supposed to be changing to bob when StatTransfer() is called by FighterButtonClick. According to the debugger everything is working right.
I've taken out some extra variables and stuff unrelated to the problem at hand.
public partial class MainForm : Form
{
public static string VariableLabel1;
public static string Variable2;
Random _r = new Random();
public MainForm()
{
InitializeComponent();
}
void CLoop()
{
while(true)
{
SetInfo();
}
}
public void SetInfo()
{
this.pcNameLabel.Text = VariableLabel1;
}
void ChClassButtClick(object sender, EventArgs e)
{
CharStats form = new CharStats();
form.Show();
}
}
This is a seperate windows form window.
public partial class CharStats : Form
{
public CharStats()
{
InitializeComponent();
}
void StatTransfer()
{
MainForm Mform = new MainForm();
MainForm.VariableLabel1 = "Bob";
Mform.SetInfo();
}
void FighterButtonClick(object sender, EventArgs e)
{
Fighter();
StatTransfer();
}
}
In these lines
void StatTransfer()
{
// This is a new instance of MainForm, not the original one
MainForm Mform = new MainForm();
MainForm.VariableLabel1 = "Bob";
Mform.SetInfo();
}
you create a new instance of MainForm and this instance is never displayed. This hidden instance contains the label that you are trying to change, but you cant't see it.
The simplest workaround to the problem is to pass the calling instance of MainForm to CharStats form when you initialize it
void ChClassButtClick(object sender, EventArgs e)
{
CharStats form = new CharStats(this);
form.Show();
}
Now you should change the constructor of CharStats to receive the passed instance and save it in a global variable inside the CharStats class
public partial class CharStats : Form
{
private MainForm _callingForm;
public CharStats(MainForm callingForm)
{
InitializeComponent();
_callingForm = callingForm;
}
.....
And use this saved instance where you need it
void StatTransfer()
{
_callingForm.VariableLabel1 = "Bob";
callingForm.SetInfo();
}
}
EDIT By the way, you dnn't need to use static variable for this to work. Simply change the method MainForm.SetInfo to receive a string and pass Bob when you call it
public void SetInfo(string newText)
{
this.pcNameLabel.Text = newText;
}
From CharStats
void StatTransfer()
{
callingForm.SetInfo("Bob");
}
MainForm is not set to display anywhere. I believe you want to add it to your CharStats form like so:
void StatTransfer()
{
MainForm Mform = new MainForm();
MainForm.VariableLabel1 = "Bob";
Mform.SetInfo();
this.Controls.Add(Mform);
}

C# call function from outside current class

Currently have a mainForm.cs which calls a class panel.cs
panel.cs holds multiple pictureboxes with events such as _click, _mousedown, _mouseup
I wish to call a function in mainForm.cs from panel.cs
do i need to use a callback / delegate. Is there another way to access this function
I have tried
Main main = new Main();
main.functioninMain does not work
any help or direction would be appreciated.
for example
panel.cs
private void pb_button1_Click(object sender, EventArgs e)
{
this.BeginInvoke(new Action(main.functioninMain));
}
You should not instantiate another object of MainForm, which creates a duplicate and all the objects withing the new MainForm will not have the values of your actual MainForm.
Approach 1
You can try creating a static instance of you MainForm like below
public partial class MainForm : Form
{
public static MainForm Instance = null;
public MainForm()
{
InitializeComponent();
Instance = this;
}
public SomeMethod()
{
}
}
Now if you have your panel class, then you can easily access public methods and variables of MainClass
class Panel : Form
{
public Panel()
{
MainForm.Instance.SomeMethod();
}
}
Edit: Pass Handle as parameter to the form (From Ben Voigt's suggestion)
Approach 2:
As Ben suggested, it is also important to have a safer code, so much cleaner approach will be passing handle of the control as parameter and then to access them.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
TestClass test = new TestClass();
test.ModifyText(textBox1);
}
}
public class TestClass
{
public void ModifyText(TextBox textBox)
{
textBox.Text = "New text";
}
}
If we can use delegate & events something like this
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Panel formPanel = new Panel();
formPanel.OnPanelClick += new Panel.OnPanelButtonClick(formPanel_OnPanelClick);
formPanel.Show();
}
void formPanel_OnPanelClick(string a)
{
MessageBox.Show(a);
}
}
public partial class Panel : Form
{
public delegate void OnPanelButtonClick(string a);
public event OnPanelButtonClick OnPanelClick = null;
public Panel()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (OnPanelClick != null)
{
OnPanelClick("from Panel.cs");
}
}
}
You should avoid circular dependencies at all costs (class A depends on class B, and class B depends on Class A).
There are so many ways to do this, but perhaps one of the easier ways is to use an interface. mainForm.cs implements it like this:
public class mainForm : IMainForm {
// This method is defined in the interface, so mainForm
// must implement it.
public string GetStringFromMainForm() {
return "Hello from MainForm";
}
public void CreatePanel() {
// pass in a reference to myself so panel knows how to
// talk to me.
var panel = new Panel(this);
}
}
And IMainForm (the interface) could look like this:
public interface IMainForm {
string GetStringFromMainForm();
}
Then your panel class can talk to the Main form without having to reference mainForm.cs explicitly:
public class Panel {
// use a private variable to keep track of main form
private IMainForm _mainForm;
// Constructor: pass in a class that implements IMainForm. It isn't
// a type of MainForm, so there's no dependency on the concrete class.
public Panel(IMainForm mainForm) {
_mainForm = mainForm;
}
public void TalkToMainForm() {
var resultFromMainForm = _mainForm.GetStringFromMainForm();
Console.WriteLine(resultFromMainForm);
}
}

Categories

Resources