So, I have two forms. The form1 has a button to open the form2. In the form2 I have a list of elements that I fill with elements I create in the form2. My problem is, when I close my form2 and reopen it, my list is empty. I know that is because Im initializing my list again (ListaComida = new List<Comida>();), so I get my data erased but I dont see how to solve this.
My code
Form1
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void addDia_Click(object sender, EventArgs e)
{
string dia = (DateTime.Today.ToString("dd/MM/yyyy"));
TabPage myTabPage = new TabPage(dia);
tabControl1.TabPages.Add(myTabPage);
}
private void AddComida_Click(object sender, EventArgs e)
{
FormAddComida addComida = new FormAddComida();
DialogResult resultaod = addComida.ShowDialog();
}
}
Form2
public partial class FormAddComida : Form
{
public List<Comida> ListaComida;
public FormAddComida()
{
InitializeComponent();
ListaComida = new List<Comida>();
}
private void addComidaAdicionar_Click(object sender, EventArgs e)
{
Comida comidaAdicionada = new Comida(tbNome.Text,
Convert.ToInt32(tbCalorias.Text),
Convert.ToInt32(tbHidratos.Text),
Convert.ToInt32(tbProteinas.Text),
Convert.ToInt32(tbGorduras.Text)
);
ListaComida.Add(comidaAdicionada);
RefreshListaComida();
}
private void RefreshListaComida()
{
lbListaComida.Items.Clear();
lbListaComida.Items.AddRange(ListaComida.ToArray());
}
private void AddComidaCancelar_Click(object sender, EventArgs e)
{
this.Close();
}
}
You can use MemoryCache, even if you close your form your List will stay in Memory and you can retrieve by the Key. But if you need to save this data permanently (or long time running the app )i recommend you store in a DB.
using System.Runtime.Caching;
private ObjectCache cache = MemoryCache.Default;
public class Food
{
public string Name { get; set; }
public double Price { get; set; }
}
public void AddFood()
{
FoodList.Add(new Food { Name = "Pizza", Price = 10 });
FoodList.Add(new Food { Name = "Fries", Price = 5 });
cache.Add("UserCacheFood", FoodList, DateTimeOffset.MaxValue);
}
public List<Food> ReturnListFromCache()
{
return (List<Food>)cache.Get("UserCacheFood");
}
private void button1_Click(object sender, EventArgs e)
{
AddFood();
var result = ReturnListFromCache();
}
private void button2_Click(object sender, EventArgs e)
{
var ret2 = ReturnListFromCache();
}
Related
I am new to C# and I want to utilize the forms with one another.
I have 2 forms. (1)MMCMLibrary_home and (2)MMCMLibrary_reserve.
In this project, I'm in the stage of changing the label background colors in Form 1 but can't seem to utilize Form 2 to process it.
These are my necessary codes so far:
FORM 1
namespace MMCM_Library
{
public partial class MMCMLibrary_home : Form
{
public static MMCMLibrary_home instance;
//DCR1 Labels
public Label lbl1_1;
public Label lbl1_2;
public Label lbl1_3;
public Label lbl1_4;
public MMCMLibrary_home()
{
InitializeComponent();
instance = this;
lbl1_1 = lblDCR1_9;
lbl1_2 = lblDCR2_11;
lbl1_3 = lblDCR1_1;
lbl1_4 = lblDCR1_3;
public void btnDCR1_Click(object sender, EventArgs e)
{
var reserveDCR1 = new MMCMLibrary_reserve();
reserveDCR1.Show();
}
public void btnDCR2_Click(object sender, EventArgs e)
{
var reserveDCR2 = new MMCMLibrary_reserve();
reserveDCR2.Show();
}
public void btnDCR3_Click(object sender, EventArgs e)
{
var reserveDCR3 = new MMCMLibrary_reserve();
reserveDCR3.Show();
}
public void btnDCR4_Click(object sender, EventArgs e)
{
var reserveDCR4 = new MMCMLibrary_reserve();
reserveDCR4.Show();
}
}
}
FORM 2
when I click any reserve now button in form 1 it will open form 2. However, if I pick a radio button, the background change will always be applied to Discussion Room 1 even I reserved for discussion room 2
namespace MMCM_Library
{
public partial class MMCMLibrary_reserve : Form
{
public static MMCMLibrary_reserve instance;
public MMCMLibrary_reserve()
{
InitializeComponent();
instance = this;
}
private void MMCMLibrary_reserve_Load(object sender, EventArgs e)
{
}
private void splitContainer1_Panel2_Paint(object sender, PaintEventArgs e)
{
}
private void splitContainer1_Panel1_Paint(object sender, PaintEventArgs e)
{
}
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
}
private void radioButton1_CheckedChanged_1(object sender, EventArgs e)
{
}
private void btnDCR1_Click(object sender, EventArgs e)
{
}
public void btnDCRoomsReserve_Click(object sender, EventArgs e)
{
if (rbtn9.Checked)
{
MMCMLibrary_home.instance.lbl1_1.BackColor = System.Drawing.Color.Red;
}
}
}
}
Can you help me to device an efficient way to solve this. Can you also suggest a database method suitable for my beginner project.
You've said that:
the background change will always be applied to Discussion Room 1
Well, yes. It seems you don't pass specific object into Form2. There's strightforward:
MMCMLibrary_home.instance.lbl1_1.BackColor = System.Drawing.Color.Red;
So you'll be always changing backcolor of lbl1_1 of your Form1. What needs to be done is to indicate which room has been selected. You can assign room after you click the button by passing the int parameter:
public void btnDCR1_Click(object sender, EventArgs e)
{
var reserveDCR1 = new MMCMLibrary_reserve(1);
reserveDCR1.Show();
}
or:
public void btnDCR2_Click(object sender, EventArgs e)
{
var reserveDCR2 = new MMCMLibrary_reserve(2);
reserveDCR2.Show();
}
Then, in Form2, at the very top, add something like:
int room; to be able to assign the room number in Form2:
public MMCMLibrary_reserve(int roomNumber)
{
InitializeComponent();
room = roomNumber;
instance = this;
}
And then you could just select room you clicked, by:
public void btnDCRoomsReserve_Click(object sender, EventArgs e)
{
if (rbtn9.Checked)
{
if(room == 1)
{
MMCMLibrary_home.instance.lbl1_1.BackColor = System.Drawing.Color.Red;
}
else if(room == 2)
{
MMCMLibrary_home.instance.lbl1_2.BackColor = System.Drawing.Color.Red;
}
else if(room == 3)
{
MMCMLibrary_home.instance.lbl1_3.BackColor = System.Drawing.Color.Red;
}
else if(room == 4)
{
MMCMLibrary_home.instance.lbl1_4.BackColor = System.Drawing.Color.Red;
}
}
else if(radioButton2.Checked)
{
//etc.
}
else if(radioButton3.Checked)
{
//etc.
}
else if(radioButton4.Checked)
{
//etc.
}
}
I think that was the problem. Try it and let us know.
I have this code:
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public class Human
{
public string Name;
public Human(string name)
{
Name = name;
}
}
private void Form1_Load(object sender, EventArgs e)
{
textBox1.Text = "Jane";
}
private void AddNewHuman_Click(object sender, EventArgs e)
{
Human h1 = new Human(textBox1.Text);
}
}
}
Is there a way, how to create a new instance of Human whenever I click the Button(AddNewHuman_Click)?
After clicking few times on the button, there will still be only one Human h1, right?
You will have to create list of object to store multiple object of human class.
I do changed here for you. I hope it will work for you.
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public class Human
{
public string Name;
public Human(string name)
{
Name = name;
}
}
List<Human> objHumanList;
private void Form1_Load(object sender, EventArgs e)
{
objHumanList=new List<Human>();
textBox1.Text = "Jane";
}
private void AddNewHuman_Click(object sender, EventArgs e)
{
Human h1 = new Human(textBox1.Text);
objHumanList.add(h1);
/** Or
objHumanList.add (new Human(textBox1.Text))
**/
}
}
}
You can create a list of Humans and keep on adding a new Human to the list whenever the button is clicked.
I have two forms, form1 and form2.
form1 has three buttons, button1(vanilla), button2(chocolate) and button3(nextpage).
form2 has a listView1
On form1 the user will click button1 or/and button2. If they click on both how do I display it underneath onto the next row on the listView1 on form2.
There's a screenshot below which shows what I mean
public partial class form1 : Form
{
public form1()
{
InitializeComponent();
}
public static string buttonValue = "";
public static string buttonValue1 = "";
public void button1_Click(object sender, EventArgs e)
{
buttonValue = "Vanillaaaa";
}
private void button2_Click(object sender, EventArgs e)
{
buttonValue1 = "Chocolate";
}
private void button3_Click(object sender, EventArgs e)
{
form2 form2 = new form2(buttonValue + buttonValue1);
form2.Show();
this.Hide();
}
}
Form2
public partial class form2 : Form
{
private string _passedValue = "";
private string _passedValue1 = "";
public form2(string passedValue)
{
InitializeComponent();
_passedValue = passedValue;
listView1.Items.Add(_passedValue);
listView1.Items.Add(_passedValue1);
}
I want the Chocolate to show underneath Vanilla on the next line.
Because you are concatenating both the strings to one string and passing that to the second forms constructor. What you should do is to pass a list of strings and loop through each one of them and add that to your listView.
So update your second form's constructors to accept a list of strings.
public partial class form2 : Form
{
public form2(List<string> passedValues)
{
InitializeComponent();
foreach(var item in passedValues)
{
listView1.Items.Add(item);
}
}
}
And in your first form,
public partial class form1 : Form
{
private string vanilla = "Vanilla";
private string chocolate= "Chocolate";
private List<string> _values= new List<string>();
public form1()
{
InitializeComponent();
}
public void button1_Click(object sender, EventArgs e)
{
if (!_values.Contains(vanilla))
{
_values.Add(vanilla);
}
}
private void button2_Click(object sender, EventArgs e)
{
if (!_values.Contains(chocolate))
{
_values.Add(chocolate);
}
}
private void button3_Click(object sender, EventArgs e)
{
form2 form2 = new form2(_values);
form2.Show();
this.Hide();
}
}
EDIT : If you want to allow multiple instances of one string(When user clicks a button more than one time), You can simply remove the if(!_values.Contains( condition check before adding the item to the list. If you want to get the quantity of a string, you need to group it then do the count.
var grouped = _values.GroupBy(k => k, v => v,
(k, v) => new { Name = k, Count = v.Count()}).ToList();
foreach (var item in grouped)
{
var name = item.Name;
var count = item.Count;
//do something with the name and count now.
}
You can do some trick like
public partial class form1 : Form
{
public form1()
{
InitializeComponent();
}
public static string buttonValue = "";
public void button1_Click(object sender, EventArgs e)
{
buttonValue = "Vanillaaaa";
}
private void button2_Click(object sender, EventArgs e)
{
buttonValue += "~Chocolate";
}
private void button3_Click(object sender, EventArgs e)
{
form2 form2 = new form2(buttonValue);
form2.Show();
this.Hide();
}
public partial class form2 : Form
{
public form2(string passedValue)
{
InitializeComponent();
string[] _passedValue = passedValue.Split('~');
listView1.Items.Add(_passedValue[0]);
listView1.Items.Add(_passedValue[1]);
}
This question already has answers here:
Passing Values Between Windows Forms c# [duplicate]
(2 answers)
Closed 7 years ago.
I have a 2 different forms, in one I generate a list of customers, in the other one I need to retrieve the information added into the list. How can I pass the list to my second form?
Here's the first form
List<Customers> new_customer = new List<Customers>();
private void newCustomer_Load(object sender, EventArgs e)
{
}
private void fNameTxtBox_TextChanged(object sender, EventArgs e)
{
}
private void lNameTxtBox_TextChanged(object sender, EventArgs e)
{
}
private void addressTxtBox_TextChanged(object sender, EventArgs e)
{
}
private void phoneNumTxtBox_TextChanged(object sender, EventArgs e)
{
}
private void emailTxtBox_TextChanged(object sender, EventArgs e)
{
}
private void IDTxtBox_TextChanged(object sender, EventArgs e)
{
}
private void addNewCustButton_Click(object sender, EventArgs e)
{
if (fNameTxtBox.Text != "" && lNameTxtBox.Text != "" && addressTxtBox.Text != "" && phoneNumTxtBox.Text != "" && emailTxtBox.Text != "" && IDTxtBox.Text != "")
{
new_customer.Add(new Customers { FName = fNameTxtBox.Text, LName = lNameTxtBox.Text, Address = addressTxtBox.Text, phoneNum = phoneNumTxtBox.Text, emailAdd = emailTxtBox.Text, ID = int.Parse(IDTxtBox.Text) });
MessageBox.Show("Thanks for Registering");
}
else
{
MessageBox.Show("Customer not added! Please fill out the entire form!");
}
}
}
}
And here's the second form:
namespace WindowsFormsApplication1
{
public partial class Current_Customers : Form
{
public Current_Customers()
{
InitializeComponent();
}
private void currCustComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
}
}
}
Create a new constructor of form2 like this and also create a list in second form as well.
public partial class Current_Customers : Form
{
List<Customers> new_customer = new List<Customers>();
public Current_Customers(List<Customers> customers)
{
new_customer=customers;
}
}
And when you will create object of this form in form1 do this
Current_Customers cus=new Current_Customers(new_customer);
This will pass list to second form.
You have two possible ways of doing this.
1) Make the lists public fields / Properties on both forms. If both forms exist in the same scope, they can reference each other.
2) Add the list to a third class, preferably a static class, that both forms can access. This would be my personal preference.
public static class StaticData
{
public static readonly List<Customers> _Customers = new List<Customers>();
public static List<Customers> CustomerList
{
get
{
if (_Customers.Count < 1)
{
//Load Customer data
}
return _Customers;
}
}
}
public class Form1
{
private List<Customers> new_customer = null;
public Form1()
{
this.new_customer = StaticData.CustomerList;
}
}
public class Current_Customers
{
private List<Customers> new_customer = null;
public Current_Customers()
{
this.new_customer = StaticData.CustomerList;
}
}
It has to be though that my example here is not really threadsafe and is meant to just point you in the right direction.
Trying to get this active in another form. I want the objects from listBox1 to go to the labels: label3 and label4 in form2. PropertyA should assign to label3 and PropertyB to label4. It will simply load the data from form1. The question is in the form2 code. When an item is selected form the listbox it will write the properties for prepare them for the next form2 instance.
Most of this is fairly short and simple code...
Made a simple program to illustrate...
FOUND THE SOLUTION.... SEE FORM2, it was a problem of casting between forms the listbox1.SelectedItems as object of SpecialClass type.
Class
namespace WindowsFormsApplication1
{
class SpecialClass
{
public string PropertyA { get; set; }
public double PropertyB { get; set; }
#region [Methods]
public override string ToString()
{
return string.Format("PropertyA: {0}, PropertyB: {1}", this.PropertyA, this.PropertyB);
}
#endregion
}
}
Form1
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void AddBtn_Click(object sender, EventArgs e)
{
SpecialClass o = new SpecialClass();
o.PropertyA = textBox1.Text;
o.PropertyB = double.Parse(textBox2.Text);
listBox1.Items.Add(o);
}
#region [Currently unused methods]
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
private void label2_Click(object sender, EventArgs e)
{
}
#endregion
private void openNewForm(object sender, EventArgs e)
{
Form2 form2 = new Form2(this);
form2.Show(this);
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
SpecialClass o = ((ListBox)sender).SelectedItem as SpecialClass;
label3.Text = o.PropertyA.ToString();
label4.Text = o.PropertyB.ToString();
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}
Form2
namespace WindowsFormsApplication1
{
public partial class Form2 : Form
{
Form1 form1Data = new Form1();
public Form2(Form1 _form1)
{
InitializeComponent();
form1Data = _form1;
}
private void label3_Click(object sender, EventArgs e)
{
SpecialClass oF2 = form1Data.listBox1.SelectedItem as SpecialClass;
label3.Text = oF2.PropertyA.ToString();
}
private void Form2_Load(object sender, EventArgs e)
{
}
}
}