I have Form1.cs which has two buttons say "ADD" and "EDIT".
Clicking "ADD" shows dialog Form2.cs.
Form2 has a TextBox and a ComboBox. Say we enter value "A" in textbox and select "A" from ComboBox.
Then close Form2.
Then when EDIT button is clicked on Form1, Form2 should show up with "A" in textbox and "A" selected in ComboBox.
This is a simple explanation. The real form I am using has around 10-12 different controls including combobox, checkbox, textbox etc.
My main doubt is where and how do we save these control values.
Is there a specific approach to this type of DialogBoxes that I am missing?
Create class, that would store values that you want to pass (let's call it Foo).
Form2 should then have a property. In the setter of the property, set controls:
public partial class Form2 : Form
{
private Foo _bar;
public Foo Bar
{
set
{
_bar = value;
//set your controls here
}
}
On Edit button, set property like this:
Form2 form2 = new Form2();
form2.Bar = bar; //bar contains values to edit
Then put a Save button on Form2, that would save values back from controls to this object.
For every control I would have a field in Foo class, eg. string for textboxes, bool for checkboxes and enum or int for comboboxes (where integer value would equal selected index).
Alternatively, you could use Dictionary class instead and have key and value pair for every control.
You can also have some enum, if your form looks or behaves differently in New and Edit mode.
Your Dialog Form should have a field containing the properties/fields you want, a copy a business object for example. Then you pass it or initialize it in your dialog constructor or Load, depending the behavior you want. From there you can create / initialize your controls.
If you want a built in system you may wanna take a look to the PropertyGrid (which you could embedded in a dialog (to fit your question))
Do you want to just load the last value user entered there?
For instance he writes "text" on the textbox and chooses "A" combobox it should be pre-selected next time you open it?
Edit: Then instead of closing it using Form.Close make it so that it hides. Form1.Hide. Next time it opens values are still saved. Unless application has been closed. In the other hand, users might click on the close button in the windows form. You can either make it "unclickable" throught proprieties or just configure it using events i think.
Create a method on Form2, where you will set values into textBox and select an item in comboBox. Call this method just after instantiating form2 and before showing it.
Example:
public Form2()
{
InitializeComponent();
comboBox1.Items.AddRange(new string[] { "a", "b", "c" });//fill comboBox your way on a loading time
}
public void UpdatingControls(string a, string b)
{
textBox1.Text = a;
comboBox1.SelectedText = b;
}
//on form2;
Form1 f2;
private void OpenForm2Button_Click(object sender, EventArgs e)
{
f2 = new Form2();
f2.UpdatingControls("a", "b"); //a will go into textBox, b will be choosen in comboBox
}
public Form2(string form1Textbox)
{
InitializeComponent();
form2Textbox.Text = form1Textbox;
}
Related
I am new to C#. I am using windows forms and I have Form1 which contains 2 buttons ( one to create user control at run time and the other creates buttons on user control at run time).
This code creates user control and FlowLayoutPanel (to organize button position) if you click add_UserControl button. And then it creates buttons on FlowLayoutPanel if you click Add_Buttons button and it is all done at run time.
Now in Form1 let's say I created user control and FlowLayoutPanel and then created 5 buttons , how can I save the properties/details of this user control with its FlowLayoutPanel and 5 buttons in SQL database so I can use them later when I run the program? I have been thinking about an idea and I reached the internet but no luck.
Any idea? Please help me. Thank you
public partial class Form1 : Form
{
FlowLayoutPanel FLP = new FlowLayoutPanel();
UserControl uc = new UserControl();
private void add_UserControl_Click(object sender, EventArgs e)
{
uc.Height = 700;
uc.Width = 900;
uc.BackColor = Color.Black;
Controls.Add(uc); //add UserControl on Form1
FLP.Height = 600;
FLP.Width = 800;
FLP.BackColor = Color.DimGray;
uc.Controls.Add(FLP); // add FlowLayoutPanel to UserControl
}
private void Add_Buttons_Click(object sender, EventArgs e)
{
//####### add buttons to FlowLayoutPanel ############
Button dynamicButton = new Button();
dynamicButton.Height = 50;
dynamicButton.Width = 200;
dynamicButton.BackColor = Color.Green;
dynamicButton.ForeColor = Color.Blue;
dynamicButton.Text = "";
FLP.Controls.Add(dynamicButton);
}
}
OK, First you need to create a class that will represent one of the buttons with the properties you need.
class MyButton
{
public string ButtonText {get;set;}
}
Everytime you click and create a button, you actually create an object of this class and add it to a collection or list. Then you would have some other code watching over the collection, and every time it gets a new entry, it creates a new button and sets its Button text to the text property. when a member of list is gone, it removes the button.
If you need more properties to be remembered (color, size, font, ...) you add them to the class as well. If you need for other controls, as well, .... you can always create common parent controls.
Simple.
If you want to be able to reload it, you could define the MyButton class as serializable and store it in xml file, and upon build, reload it.
You should watch into WPF and it's MVVM pattern. It's pretty much similar to it. Also have a look into command pattern, usefull pattern when it commes to this.
You can remember the FlowLayoutsPanels in one SQL table and in another table you could save the buttons which belong to these FlowLayoutPanels.
On Form Load or Application Load, you could check if there are already FlowLayoutPanels and correspending Buttons do exist in the SQL db and if yes then create them, else do nothing.
I have a datagridview called logDataGridView in my AnalyzerForm project.
In order to access to it's DataSource property from the other from, called Form2, in the project, below access field has been defined into the AnalyzerForm.Designer.cs:
Public System.Windows.Forms.DataGridView _DGV
{
get {return this.logDataGridView;}
set {logDataGridView.DataSource = value;}
}
And finally, i try to use a filled DataTable called t from the Form2:
AnalyzerForm AZ = new AnalyzerForm();
AZ._DGV.DataSource = t;
Nothing will be shown into the logDataGridView!!!
Does anybody have any idea about the wrong part?
Actually the wrong part of the progress is just reinstantiation of the parent form, as below:
AnalyzerForm AZ = new AnalyzerForm();
One must use the very parent form reference, is which responsible for launching the child form. It is possible to define a secondary constructor for the child parent and feed a parent form object just inside of it:
ParentForm pForm;
public childForm(ParentForm FRM)
{
pForm = FRM;
// Then component initializing...
}
Finally, the required component of the parent form (is which a datagridview, in my case), is possible:
pForm._DVG.DataSource = t;
I have a C# Form that prints multiple instances of a User Control. Let's say that the form prints 5 instances of the User Control (Please see the link attached). How can I store/save the data inputted in all User Controls? Thanks
Here is the screenshot of the C# Form:
You'll have to store the User Controls when you instantiate them in a List or something.
You could have a class like this:
class SomeUC : UserControl
{
public SomeUC()
{
}
// A public method.
public string GetData()
{
return textBox1.Text;
}
}
Where textBox1 is the Name of a TextBox in your SomeUC
And then inside your main or something.
// Instantiate a List that will hold your UserControls, this has to be outside all methods
List<SomeUC> list = new List<SomeUC>();
// And now when you want to build your UCs
// Instantiate your UserControl
SomeUC uc1 = new SomeUC();
// Store your UserControl in a List or something (Can't help you with that)
list.Add(uc1);
Add as much as you want.
A List is not the only way you can do that, but since you don't know how many UserControls you're going to build beforehand, it makes since to use a List.
And then you can access them from the list by their index.
SomeUC uc1 = list[0];
string data = uc1.GetData();
This is an example of accessing one control (the TextBox) in your SomeUC. For other classes (such as the ComboBox) the interaction is different. Meaning you won't have a Text property in the ComboBox. You'll have to figure out things like that on youself. A little research is what it takes. You can always come back if you couldn't find a solution for something.
You can create a property like this for each item in user control.
public string DG
{
get
{
return txtDG.Text;
}
set
{
txtDG.Text = value;
}
}
Then you can access the control value by using following line in your form.
supposed you have created a usercontrol MyControl and you have placed some object of this control in FlowLayoutPenal (pnlFLP).
To get value from control
string DG = ((MyControl)pnlFLP.Controls[0]).DG;
To set value in control
((MyControl)pnlFLP.Controls[0]).DG = "1";
Try this code for accessing user control in the page
Dim txtName As TextBox = TryCast(UserControlName.FindControl("txtName"), TextBox)
I have a WPF main window, which contains a toolbar with buttons and a tabcontrol that is displaying a page with a listbox. The page is hosted on a frame, and the frame is set on the tab I selected.
When I click on a button on my toolbar, a new window pops up with a textbox and a submit button. When I press the submit button, I want to insert the textbox contents into the listbox that's on the main window. However, nothing displays in the listbox. I tried listbox.Items.Add() but it still won't display.
public partial class AddNewCamper : Window
{
public AddNewCamper()
{
InitializeComponent();
}
private void btnNewSubmit_Click(object sender, RoutedEventArgs e)
{
CampersPage c;
// Converting string to int b/c thats what camper() takes in.
int NewAge = Convert.ToInt16(txtNewAge.Text);
int NewGrade = Convert.ToInt16(txtNewGrade.Text);
// Create a new person
Camper person = new Camper(NewAge, NewGrade, txtNewFirstName.Text);
txtNewFirstName.Text = person.getName();
// Trying to add the first name of the person to display on the listbox of another window.
c.testListBox.Items.Add(txtNewFirstName.Text);
}
You can follow any of the following approaches. But based on your comments I guess solution 3 suits you.
1) Try initializing c first. You can't use an object without allocating memory for it.
2) If you want to use the same object, use the reference of the object created in the MainWindow
in the required class.
something like this should work:
CampersPage c = [reference to CampersPage object in MainWindow]
then add items to your listbox
3) If you want to use the listbox object, make your CampersPage Class static.
Making it static would not require you to initialize your class explicitly.
public static CampersPage {
// do something here
}
Make sure that you declare your listbox in CampersPage as public.
Then in the class requiring your listbox defined in CampersPage, do the following
CampersPage.testListBox.Items.Add(txtNewFirstName.Text);
4) If the classes are in the same namespace, you can declare listbox as a global public property and access it from rest of the classes in the same namespace.
I have 2 forms in my project, form1 and form2. When I click in a button in form1 I run this code:
Form tempform = new Form2();
tempform.Show();
In my code for Form2 I have a label which I now need to change the text.
How can I access the label?
I tried:
tempform.label1.value = "new text"
And that didn't work, I even tried to access using the Controls collection but I think I messed that up. Is there any way I can access the label? OR is there any way I can pass a value to that new form and then have that form alter the label text.
Thanks
If the label value should only be set once, when the form is created, then use a constructor for Form2 like this:
public Form2(string labelValue)
{
_labelValue = labelValue;
}
and then call that constructor when you create the form.
Alternatively, if the label changes over the lifetime of the form, make a public property:
public string LabelValue
{
get { return label1.Text; }
set { label1.Text = value; }
}
Also I would recommend naming the parameters and/or properties to reflect the meaning of the value, for example "titleText" instead of "labelValue". That way Form2 can decide how it wants to display the information (in the title bar, a label, a textbox, etc), and Form1 doesn't have to worry about that.
Edit: Consume the LabelValue property like this:
Form2 newForm = new Form2(); // Assign object to a Form2 instead of Form
newForm.LabelValue = "new text";
newForm.Show();
Controls have protected access by default. You can change that to public, or you can add a method/property to your form2 class to set the label and call that (latter method is generally preferred to preserve encapsulation and because the designer may want to overwrite your public change.).