C# Using function from another file - c#

Ok, so, I have functions.cs file where i stored following function
public static void Global_Reset()
{
Form1 blok = new Form1();
blok.userControl1.Visible = false;
blok.userControl2.Visible = false;
blok.userControl3.Visible = false;
if (Properties.Settings.Default.client == 1)
{
blok.userControl1.Visible = true;
MessageBox.Show("First");
}
else if (Properties.Settings.Default.client == 2)
{
blok.userControl2.Visible = true;
MessageBox.Show("Second");
}
else if (Properties.Settings.Default.client == 3)
{
blok.userControl2.Visible = true;
MessageBox.Show("Third");
}
else
{
MessageBox.Show("Error");
}
}
When I call fun.Global_Reset() in Form1 or in any user control that is used in Form1, visibility never changes but I got messages (First, Second, Third). Is there any way to solve this?
I tried to use this directly in Form1 and it used to work, but when I call it from userControl that was used in Form1 it's not working again.

This is the form you're modifying:
Form1 blok = new Form1();
It only exists during the scope of that method (function), and it is never shown to the user. It's not the form instance you're seeing on the screen.
As an analogy... Imagine the form you're seeing is a car. What you're doing is getting another car that looks just like it and putting something in the trunk of that car, then noticing that what you put in the trunk of the second car can't be found in the trunk of the first car.
Instead of creating a new form instance, pass the existing instance to this method:
public static void Global_Reset(Form1 blok)
{
// don't create an instance here, just use the blok that was passed
}
Then pass that instance from your form, for example:
fun.Global_Reset(this);

Related

changing textlabel in form1 using different class

having a bit of a problem changing the label text when a button is pressed. my code looks like this. i searched a bit in this forum and tried this solution in form1 i have this code.
public string info
{
get
{
return label11.Text;
}
set
{
label11.Text = value;
}
}
in class search i have this
public void fighting()
{
character tom = new character();
Form1 f = new Form1();
Random explore = new Random();
int exploration = explore.Next(0, 3);
if (character.location == "Forest" || character.location == "Dungeon")
{
switch (exploration)
{
case 0:
f.info = "You didnt find anything";
f.Refresh();
f.herodamage = exploration.ToString();
break;
...
the button has this
public void button8_Click(object sender, EventArgs e)
{
Search find = new Search();
find.fighting();
}
what am i doing wrong? everytime i press the button the text wont change but it works because it does change a buttons text.
Fighting method is creating a new instance of Form1, different from your UI.
While it is updating label1.Text, it refers to different Form1.
My suggestion is for refactoring of your code to make responsibilities more clear.
Something like
var info = find.fighting(); // Where fighting returns string, instead of creating new Form1 and setting value, just return the value.
this.info = info;
If you still insist to update UI from search method, which is not correct way to approach this problem, you can pass around Form1 from the parameter.
Search find = new Search(this); // Store it as instance of Search class.
find.fighting(); // fighting should never create new instance of Form1 (reason of problem you are facing)
Instead of creating a new instance of Form1 you need to get a reference to the already existing instance of this form.
One simple way to do this is to use the Application.OpenForms property:
character tom = new character();
Form1 f = Application.OpenForms.OfType<Form1>().FirstOrDefault();
Random explore = new Random();
...

C# Take combobox item from one form and add its name as text to another

Ok so I'm attempting to create a simple game. In a nutshell it's a resource management game where the player will attempt to manage a thieves guild. In regards to running missions I've created a Thief class, a new instance of which is created when a new thief is recruited. I have coded within the thief class the ability to gain experience and level up.
Here's my specific problem:
I want the player to be able to select which thief/thieves to send on a mission. I have thought about it and figured that opening a new form and populating it with checkboxes is the easiest way to allow this. These checkboxes will be related to a List<thief> of thieves, the player then checks the thieves s/he wants to send and these are then stored in another List<thief> and passed on to the run mission function.
I've built a separate project with the intention of testing and playing around with this before putting it into the main program. The test project consists of two forms: The first (frmMain) with a textbox to hold the selected options and a button to open the second form (frmSelect). Currently I can open and populate the second form (frmSelect) but when I try to add the checked options to the textbox I simply...well can't.
So far I have tried directly accessing the textbox by typing frmMain.txtOptionsDisplay in the cs file of frmSelect but it causes the following error:
An object reference is required for the non-static field, method or
property
I tried to create a new form in frmSelect and make it equal to the active instance of frmMain with: Form frmTemp = frmMain.ActiveForm; and then alter the textbox using frmTemp as a go-between but that produced the error:
'System.Windows.Forms.Form' does not contain a definition for
'txtOptionsDisplay'.
Having searched both google and stackoverflow forums I've encountered answers that I either have never heard of (Threading) or answers that I kind've recognise but can't interpret the code pasted to make it relevant to my problem (delegates).
Any advice or pointers would be fantastic.
EDIT:
frmMain code:
public frmMain()
{
InitializeComponent();
selections.Add("Option 1");
selections.Add("Option 2");
}
private void btnClick_Click(object sender, EventArgs e)
{
frmSelectOptions.Show();
int length = selections.Count();
for (int i = 0; i < length; i++)
{
CheckBox box = new CheckBox();
box.Text = selections[i];
box.AutoSize = true;
box.Location = new Point(50, 50*(i+1));
frmSelectOptions.grpControls.Controls.Add(box);
}
}
public void updateText(string option)
{
txtOptionsDisplay.Text += option;
}
}
frmSelect code:
public List<CheckBox> selectedOptions = new List<CheckBox>();
Form frmTemp = frmMain.ActiveForm;
public frmSelect()
{
InitializeComponent();
}
private void btnSelect_Click(object sender, EventArgs e)
{
foreach (CheckBox box in grpControls.Controls)
{
if (box.Checked == true)
selectedOptions.Add(box);
}
this.Hide();
}
}
I hope this formats correctly... I'm kinda new and don't know how to indent. Oh look there's a preview...
Does this help?
Your problem is that controls defined within a form by default receive the private access identifier. Hence you could just add a property along the lines of
public ControlType ProxyProperty {
get {
return txtOptionsDisplay;
}
}
Besides from that you should think about wether what you're trying is actually a good solution. Manipulating forms from one to another will become a huge clusterfuck in terms of maintenance later on.
I'd suggest using the Singleton pattern for your frmMain. This will help safeguard you from accidentally launching another instance of frmMain and at the same time, will give you access to frmMain's objects. From there, you can either write accessors to Get your txtOptionsDisplay or you can make it public. Below is an example:
public class frmMain
{
private static frmMain Instance = null;
private static object LockObj = new object();
public static frmMain GetMain()
{
// Thread-safe singleton
lock(LockObj)
{
if(Instance == null)
Instance = new frmMain();
return Instance;
}
}
public string GetOptionsDisplayText()
{
return txtOptionsDisplay.Text;
}
}
public class frmSelect
{
private void frmSelect_Load(object sender, EventArgs e)
{
// Set whatever text you want to frmMain's txtOptionsDisplay text
txtDisplay.Text = frmMain.GetMain().GetOptionsDisplayText();
}
}
If you do go this route, don't forget to update Program.cs to use frmMain's singleton.
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// Application.Run(new frmMain()); - Old method
Application.Run(frmMain.GetMain());
}

Filling one form from another

I have two forms in my project, one is with button and second one is with two textboxes.
When I am clicking the first form button, I want to fill textbox in another.
code:
secondForm secondForm = new secondForm();
secondForm.MdiParent = this.MdiParent;
secondForm.fillForm("String");
if (formShown != true)
{
secondForm.Show();
formShown = true;
}
else
{
Application.OpenForms[secondForm.Name].Focus();
}
and
public void fillForm(string text)
{
if (String.IsNullOrEmpty(priceText1.Text))
{
priceText1.Text = text;
}
else
{
priceText2.Text = text;
}
}
looks simple, but when i am clicking button second time, its not detecting text in second form text box and entering data in textbox1 instead of textbox2, why?
The problem is that when you click the button a second time you're creating a second instance of the form, and then just not showing it (you're focusing the first instance instead). You should refactor the program so that you don't do that.
private secondform secondform = null;
private void Foo()
{
if(secondForm == null)
{
secondForm = new secondForm();
secondForm.MdiParent = this.MdiParent;
secondForm.Show();
}
secondForm.fillForm("String");
secondForm.Focus();
}
So a new instance is only created if we don't already have one, we fill the data every time, and then focus the form.
P.S. there's nothing wrong with focusing the form the first time, so I just left it after the end of the if. If there was something that should only happen when it's not the first time we could add an else to the if and put the code there.
P.S.S. secondForm isn't following standard naming conventions for the name of a class. Class names should start with an upper case letter, i.e. SecondForm. Among other issues, this removes the ambiguity about whether secondForm is refering to the type, or the instance of the type.
P.S.S.S. It may not be needed functionality in your case, but we may need to properly handle the case where the child form is closed and then the button is clicked again. The easiest way of handling this is to clear out the secondForm instance field when the form is closed (letting a new one be created when the button is next clicked, if that ever happens). Closures make this really easy, we just add this line right before secondForm.Show();:
secondform.FormClosed += (s, arg) => secondform = null;

stop executing code after new form is loaded

Some method call this method which has this code:
Form frm = new Form();
frm.Show();
but i do not want to execute first method anymore after form is loaded. How can i prevent and stop loading code in forst form
Very unclear, I'm guessing that you want to make sure that only one instance of a form can be created. You do so by keeping track of the life of the instance. Like this:
private Form2 instance;
private void showForm2() {
if (instance == null) {
instance = new Form2();
instance.FormClosed += delegate { instance = null; };
instance.Show();
}
else {
instance.WindowState = FormWindowState.Normal;
instance.Focus();
}
}
Edit: question is very unclear so I give an answer based on my understanding of it...
to block execution after a form has been created, until such form is closed, try to use ShowDialog()
using(var frm = new Form1())
{
frm.ShowDialog();
// here your code is not executed until frm is closed...
//...
//...
}
Please pay attention that you do not want to create an object of type Form as that is the default base class and will not contain your controls...

Changing the property of a control on another form

Basically, I have a settings window, and when you click "OK", it's suppose to apply settings to the main form (eg, set font of a control, etc), and then close.
frmmain frm = new frmmain();
frm.OLVAltBackColor = Color.Aquamarine ;
I tried that, but it only applies the settings to that instance, and you can see it if you do frm.Show();
I'm trying to make it so the already opened form has it's control's properties changed.
What you are trying to do is not working because you are creating a NEW instance of your main form and updating that rather than the first instance. It is possible to update the main form by keeping a reference to it in your settings form... but...
...it sounds like you are approaching this from the wrong direction.
Don't make the settings form dependent on the main form. Instead create the settings form from the main dialog.
class SettingsForm : Form
{
// You need to ensure that this color is updated before the form exits
// either make it return the value straight from a control or set it
// as the control is updated
public Color OLVAltBackColor
{
get;
private set;
}
}
In your main form
(I'm assuming some kind of button or menu click)
private void ShowSettingsClicked(object sender, EventArgs args)
{
using (SettingsForm settings = new SettingsForm())
{
// Using 'this' in the ShowDialog parents the settings dialog to the main form
if (settings.ShowDialog(this) == DialogResult.OK)
{
// update settings in the main form
this.OLVAltBackColor = settings.OLVAltBackColor;
}
}
}
Apply the property change to the form that already exists and is already shown instead of creating a new form and changing that one.
In this code you're creating a new instance of the frmmain. Any changes you make to that new object will happen in the new object, not the one you actually want to change.:
frmmain frm = new frmmain(); //Creating a new object isn't the way.
frm.OLVAltBackColor = Color.Aquamarine ;
What you're looking for is a way to call on the already existant frmmain class and change the property of that.
Edit, for example:
using System;
class Statmethod
{
//A class method declared
static void show()
{
int x = 100;
int y = 200;
Console.WriteLine(x);
Console.WriteLine(y);
}
public static void Main()
{
// Class method called without creating an object of the class
Statmethod.show();
}
}

Categories