Modify value in a class then use it in another form - c#

I have form1, form2 and a class. i want to use form2 to modify a variable in a class then read that variable in form1.
The thing is that the variable doesn't change when i try to read it from form1, nor it stays after i open form2 again.
This is my code:
Form1
namespace app1 {
public partial class Form1 : Form {
Class1 md = new Class1();
public Form1() {
InitializeComponent();
}
private void loginToolStripMenuItem_Click(object sender, EventArgs e) {
Login login = new Login();
login.MdiParent = this;
login.enbctrs += new ShowFrm(enablecrts);
login.disctrs += new ShowFrm(disablecrts);
login.Show();
}
private void Form1_Load(object sender, EventArgs e) {
if (md.user == null) {
disablecrts();
stat_usr.Text = "No active user";
} else {
stat_usr.Text = md.user.ToString();
}
}
void disablecrts() {
stat_usr.Text = "No active user";
}
void enablecrts() {
stat_usr.Text = md.user;
}
}}
Form2
namespace app1.Forms {
public delegate void ShowFrm();
public partial class Login : Form {
public event ShowFrm enbctrs;
public event ShowFrm disctrs;
int ing_counter = 0;
Class1 md = new Class1();
public Login() {
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e) {
string u = "user";
string p = "pass";
if(Txt_user.Text == u && Txt_pass.Text == p) {
string msg = "Welcome: " + u + "";
MessageBox.Show(msg, "", MessageBoxButtons.OK);
md.changeusr(u);
active_user.Text = md.user.ToString();
enbctrs();
}
private void Login_Load(object sender, EventArgs e) {
if (md.user == null) {
active_user.Text = "No active user";
} else {
active_user.Text = md.user.ToString();
}
}
}}
Class1
namespace app1.Modules {
class Class1 {
public string user;
public void changeusr(string u) {
user = u;
return;
}
}}

There are a number of things that could be improved in your code. But the main issue is that when you create the Login class in your loginToolStripMenuItem_Click() method, that new Login instance is also creating a new instance of Class1 and using that instead of the instance that your Form1 knows about. So when Login changes the user value, it's changing it in a location that Form1 doesn't know anything about.
The simplest fix IMHO is to have Form1 just pass the Class1 reference to Login for it to use, instead of having Login create its own instance. For example:
public partial class Login : Form {
// ...
readonly Class1 md;
public Login(Class1 md) {
InitializeComponent();
this.md = md;
}
// ...
}
And in Form1:
private void loginToolStripMenuItem_Click(object sender, EventArgs e) {
Login login = new Login(md);
login.MdiParent = this;
login.enbctrs += new ShowFrm(enablecrts);
login.disctrs += new ShowFrm(disablecrts);
login.Show();
}
Then when Login changes the user and raises the event, it will have changed the value in the same instance Form1 is using, and so Form1 will get the desired value in its own code.

public static class global{
public static int myInt = 0;
}
public class Form1{
global.myInt = 10;
}
public class Form2{
Console.WriteLine(global.myInt.ToString());
}

Related

Parameter passing an Object instead of entire Form

I've created a simple Pokemon WinForm application with just 2 forms. Form1 shows the Pokemon and its associated values.
Upon Clicking the Edit button, Form2 appears (EditCharacter) allowing the user to edit the attributes of the character.
To get the selected Pokemon to appear in Form2 (EditCharacter), I've passed in the currentCharacter from Form1.
Here is the code for Form1.
public partial class Form1 : Form
{
CardCollection cardCollection;
public Character currentCharacter;
public Form1()
{
InitializeComponent();
cardCollection = new CardCollection();
}
private void Form1_Load(object sender, EventArgs e)
{
foreach (var keyValuePair in cardCollection.Cards)
{
cmbPokemon.Items.Add(keyValuePair.Key);
}
}
private void cmbPokemon_SelectedIndexChanged(object sender, EventArgs e)
{
currentCharacter = cardCollection.Cards[cmbPokemon.Text];
updateControls();
}
public void updateControls()
{
lblHP.Text = currentCharacter.HealthPoints.ToString();
lblStrength.Text = currentCharacter.Strength.ToString();
lblSpecialPower.Text = currentCharacter.SpecialPower;
pbPokemon.ImageLocation = #currentCharacter.FileName;
}
private void btnEdit_Click(object sender, EventArgs e)
{
EditCharacter EditChar = new EditCharacter(currentCharacter);
EditChar.ShowDialog();
}
}
And here is the code with Constructor for the EditCharacter form:
public partial class EditCharacter : Form
{
Character currentCharacter;
public EditCharacter( Character c)
{
InitializeComponent();
currentCharacter = new Character();
currentCharacter = c;
lblCharacter.Text = c.Name;
pbCharacter.ImageLocation = c.FileName;
txtPower.Text = c.SpecialPower;
tbHP.Value = c.HealthPoints;
tbStrength.Value = c.Strength;
lblHP.Text = c.HealthPoints.ToString();
lblStrength.Text = c.Strength.ToString();
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
lblHP.Text = tbHP.Value.ToString();
}
private void tbPower_Scroll(object sender, EventArgs e)
{
lblStrength.Text = tbStrength.Value.ToString();
}
private void btnSave_Click(object sender, EventArgs e)
{
currentCharacter.Name = lblCharacter.Text;
currentCharacter.FileName = pbCharacter.ImageLocation;
currentCharacter.SpecialPower = txtPower.Text;
currentCharacter.HealthPoints = tbHP.Value;
currentCharacter.Strength = tbStrength.Value;
currentCharacter.SpecialPower = txtPower.Text;
this.Close();
}
}
My question is (and I've tried), how to preserve the values set in the EditForm to appear in Form1? For example, I edit Rayquaza's HealthPoints to 0, but when I return to Form1, it hasn't changed.
You can use interface to pass the same object directly to EditCharacter from and get it back when it has been updated.
Create new interface , that contains two methods one for reading and the other for writing.
public interface ICharacterManager
{
Character ReadCharacterData();
void WriteCharacterData(Character character);
}
Update your Form1 code by applying ICharacterManager interface, like this :
public partial class Form1 : Form , ICharacterManager
{
CardCollection cardCollection;
public Character currentCharacter;
public Form1()
{
InitializeComponent();
cardCollection = new CardCollection();
}
// The currentCharacter object which will be passed to EditCharacter form.
public Character ReadCharacterData()
{
return currentCharacter;
}
// Get back Character object from EditCharacter form after updating data and pressing Save Button
public WirteCharacterData(Character character)
{
currentCharacter = character;
// Call you updateControls() Method here.
updateControls();
}
private void btnEdit_Click(object sender, EventArgs e)
{
// You can still use this code, because already the type of Form1 is IChatacterManager now.
EditCharacter EditChar = new EditCharacter(this);
EditChar.ShowDialog();
}
}
Update your EditCharacter code by adding ICharacterManager variable like this :
public partial class EditCharacter : Form
{
private ICharacterManager _characterManager;
Character currentCharacter;
public EditCharacter(ICharacterManager characterManager)
{
InitializeComponent();
_characterManager = characterManager;
// Character object which come form Form1.
currentCharacter = _characterManager.ReadCharacterData();
lblCharacter.Text = currentCharacter.Name;
pbCharacter.ImageLocation = currentCharacter.FileName;
txtPower.Text = currentCharacter.SpecialPower;
tbHP.Value = currentCharacter.HealthPoints;
tbStrength.Value = currentCharacter.Strength;
lblHP.Text = currentCharacter.HealthPoints.ToString();
lblStrength.Text = currentCharacter.Strength.ToString();
}
private void btnSave_Click(object sender, EventArgs e)
{
currentCharacter.HealthPoints = tbHP.Value;
currentCharacter.Strength = tbStrength.Value;
currentCharacter.SpecialPower = txtPower.Text;
// Check if _characterManager object is not equal to null.
if (_characterManager != null)
{
// Pass the updated object back to Form1
_characterManager.WriteCharacterData(currentCharacter);
}
this.Close();
}
Hope this was helpful.
Happy coding :) ...

C#-Winforms-How to use instance objects in different subforms?

I have a "MainForm" and a "GraphicsForm". Clicking "New" on the main form, a "GraphicsForm" will be created.
The problem is that when I create multiple "GraphicsForm", and when I want to save the content of one of the "GraphicsForm", I need to clicking "Save" on the "MainForm" and the program will save the content of the active "GraphicsForm" to a file, I don't know how to pass the content of this "GraphicsForm" to "MainForm" for storage.
MainForm.cs
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private ToolStripMenuItem _winMenuItem = new ToolStripMenuItem();
private GraphicsForm _graphicsForm;
private int _counter = 1;
private void New_Click(objec sender, EventArgs e)
{
_winMenuItem.Name = "Win";
_winMenuItem.Text = "Windows";
int item = MainMenuStrip.Items.IndexOf(_winMenuItem);
if (item == -1)
{
MainMenuStrip.Items.Add(_winMenuItem);
MainMenuStrip.MdiWindowListItem = _winMenuItem;
}
_graphicsForm = new GraphicsForm();
_graphicsForm.Name = string.Concat("Win_", _counter.ToString());
_graphicsForm.Text = _graphicsForm.Name;
_graphicsForm.MdiParent = this;
_graphicsForm.Show();
_graphicsForm.WindowState = FormWindowState.Maximized;
_counter++;
}
private void Save_Click(object sender, EventArgs e)
{
... // Problem here
}
private void Open_Click(object sender, EventArgs e)
{
... // Problem here
}
}
GraphicsForm.cs
public partial class GraphicsForm : Form
{
//StorageDoc is a class to manage all the graphics drawn by the user in the form.
private StorageDoc _storageDoc = new StotageDoc();
public GraphicsForm()
{
InitializeComponent();
}
private Canvas_MouseDown()
{
}
private Canvas_Paint()
{
}
...
Because MainForm is a MDI form, it is easy to use ActiveMdiChild to get the active child form.
class MainForm : Form
{
public void OnSaveButtonClick(object sender, EventArgs e)
{
if(ActiveMdiChild is GraphicsForm g)
Save(g);
}
}
I'm sure this has been answered before but basically, you pass in an instance of the 'data storage' to the new form.
interface ISaveForm
{
void Save();
}
class MainForm
{
private DataStorage _dataStorage;
private ICollection<ISaveForm> _forms = new List<ISaveForm>();
public void OnNew()
{
var subForm = new GraphicsForm(_dataStorage);
subForm.Show();
_forms.Add(subForm);
}
public void OnSave()
{
foreach(var form in _forms)
{
form.Save();
}
}
}
class GraphicsForm : Form,ISaveForm
{
private DataStorage _dataStorage;
public GraphicsForm(DataStorage dataStorage)
{
_dataStorage = dataStorage;
}
public void Save()
{
}
}

Passing values to User Control from Form

I've created User Control in my WFA (Windows Form Application) and I want to pass value from my MainForm.cs to UserControl.cs but I have no idea on how to do that. Here are my values I want to pass to the UserControl.cs
public partial class MainForm : Form
{
private void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (ProcOpen)
{
//THESE
int vlInt = m.ReadByte("base+007C1DAC,0x14,0x4");
int roomID = m.ReadByte("base+003CA150,0x0");
double diffValue = m.ReadDouble("base+007B4A3C,0x0,0x2c,0x10,0x7ec,0x300");
}
}
}
To
public partial class FirstCustomControl : UserControl
{
public FirstCustomControl()
{
InitializeComponent();
}
private void FirstCustomControl_Load(object sender, EventArgs e)
{
//GET THE VALUES HERE
}
}
you can define a property for your UC then set the property from the parent;
public partial class FirstCustomControl : UserControl
{
public static dynamic vlInt;
public static dynamic roomID;
public static dynamic diff;
public FirstCustomControl()
{
InitializeComponent();
}
public void NotifyValueChanged(){
label1.text = vlInt.ToString();
label2.text = roomID.ToString();
label3.text = diff.ToString();
}
private void FirstCustomControl_Load(object sender, EventArgs e)
{
}
}
Then in your MainForm
public partial class MainForm : Form
{
private void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (ProcOpen)
{
//THESE
FirstCustomControl.vlCount = m.ReadByte("base+007C1DAC,0x14,0x4");
FirstCustomControl.roomID = m.ReadByte("base+003CA150,0x0");
FirstCustomControl.diff = m.ReadDouble("base+007B4A3C,0x0,0x2c,0x10,0x7ec,0x300");
firstCustomControl1.NotifyValueChanged();
}
}
}

Accessing form1 variables from another class how?

how do I access form1 string variable from a different class?
public partial class Form1: Form
{
public Form1()
{
InitializeComponent();
}
public string deva = "123";
//button
private void button8_Click(object sender, EventArgs e)
{
deva = "456";
}
private void button9_Click(object sender, EventArgs e)
{
Other ks = new Other();
ks.test_me();
}
}
public class Other: Form1
{
//trying to access Form1 variable.
public void test_me()
{
Form1 fm = new Form1();
MessageBox.Show(fm.deva);
//deva is 123 but not 456.
//I clicked on button and values changes it form1 however from here it assigns just default value
}
//
//Does creating a new form1 will reset its values?
//Somebody please help me. how to solve this issue.
}
public partial class Form1: Form {
public Form1()
{
InitializeComponent();
}
public string deva = "123";
//button
private void button8_Click(object sender, EventArgs e)
{
deva = "456";
}
private void button9_Click(object sender, EventArgs e)
{
Other ks = new Other(this);
ks.test_me();
}
}
no need to inherit from form1, please pass the object via constructor
public class Other {
Form1 obj = null;
public Other(Form1 object)
{
this obj = object;
}
public void test_me()
{
MessageBox.Show(obj.deva);
}
}
Make your variable deva Static. Access it with Class directly not object.
public static string deva = "123";
public void test_me()
{
//Form1 fm = new Form1();
MessageBox.Show(Form1.deva);
}
Answer on the title question.
Read Jon Skeet's comment for explanation of reason why your approach not workiing.
If you want have access to the variables of another instance, then you need in someway have reference to that instance
One way pass it in the constructor of Other
public class Other: Form1
{
private readonly Form1 _Form1;
public Other(Form1 form1)
{
_Form1 = form1;
}
public void test_me()
{
MessageBox.Show(_Form1.deva);
}
}
Then where you create new instance of Other pass instance of your Form1 ti the constructor of Other
public class Form1
{
private void button9_Click(object sender, EventArgs e)
{
Other ks = new Other(this);
ks.test_me();
}
}
default value is set a every new instance
if you want to keep last value you make a static property
public static string deva = "123";

Passing data between two wpf forms as strings

trying to get data from the main form to form 2. The main form has a textbox
and a button. when the button is pressed it opens form 2 which will display the data entered in the main form as a series of text blocks.
However I cant get the data to transfer between the forms. the code is bellow.
can anyone help or suggest anything I can do differently?
WPF 1 main form:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void btnOpenForm_Click(object sender, RoutedEventArgs e)
{
//btnset: Takes the values contained in the text boxes and updates
//the student class
//properties.
Student.sFname = firstname.Text;
Student.sSname = secondname.Text;
Window1 details = new Window1();
details.Show();
}
WPF 2 code:
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void details_Load(object sender, EventArgs e)
{
Fname.Text = Student.sFname;
Sname.Text = Student.sSname;
}
private void Close_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
}
There are a number of ways to "pass data" between 2 classes. The easiest way is to expose property or method on Window1 and just set the text you need passed. Another way is to create a constructor on Window1 that takes in the data as parameters. Here is code that demonstrates these approaches.
public class Program
{
public static void Main(string[] args)
{
var c1 = new Class1();
c1.DoStuff();
}
}
public class Class1
{
public void DoStuff()
{
var c = new Class2("stuff");
var c2 = new Class2();
c2.AcceptStuff("stuff2");
c.Print();
c2.Print();
c2.MyData = "stuff3";
c2.Print();
}
}
public class Class2
{
private string _myData;
public Class2()
{
}
public Class2(string myData)
{
_myData = myData;
}
public string MyData
{
set { _myData = value;}
}
public void AcceptStuff(string myData)
{
_myData = myData;
}
public void Print()
{
Console.WriteLine(_myData);
}
}
Prints
stuff
stuff2
stuff3
I assume you have a class in MainWindow like:
`Public class Student
{
public static string sFname;
public static string sSname;
}`
When you click open button you are assigning values to those variable, but if you want to access them in another window mention the window name and then class name.
Check this code if its working?
`public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void details_Load(object sender, EventArgs e)
{
Fname.Text = MainWindow.Student.sFname;
Sname.Text = Mainwindow.Student.sSname;
}
private void Close_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
}`

Categories

Resources