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.
Related
I started out C# very recently and sorry if this question sounds dumb.
How do I add a Listbox in a Form that pops out from a Button click?
Note: The Form isn't the one that's added from the Solution Explorer whereby I can just drag a Listbox from the Toolbox to my Form.
So what I want is to create a ListBox in my file drawer1Form where I can add additional items. Thanks for the help in advance!:)
private void drawer1button_Click(object sender, EventArgs e) // Drawer 1 Button
{
drawer1Form df1 = new drawer1Form();
df1.StartPosition = FormStartPosition.CenterScreen;
df1.Show();
}
public partial class drawer1Form : Form // Creates drawer1Form
{
public drawer1Form()
{
Text = "Drawer 1 ";
}
}
Pretty much the same way as you'd do with any other object.
In the class of your form add a
private ListBox myAwesomeListBox;
Then in the button event handler add something like this:
myAwesomeListBox = new ListBox();
myAwesomeListBox.SuspendLayout();
// set all the properties that you want
myAwesomeListBox.Name = "myAwesomeListBox";
myAwesomeListBox.Location = new Point(...); // place it somewhere
myAwesomeListBox.Size = new Size(...); // give it a size
// etc...
df1.Controls.Add(myAwesomeListBox);
myAwesomeListBox.ResumeLayout();
This should be it.
I highly advise you to do it through the designer first though, and then take a look at the generated code in the form's .Designer.cs file, you'll have a very good understanding after reading through that.
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 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 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;
}
As a course project i'm building a form in c# which contains two user controls.
The first user control has a checkedlistbox and the second control has also a checkedlistbox when the first control checkedlistbox will contain list of people (male/female) and the second user control the checkedlistbox will have two options: male, female and when I click a button on the first control which says: "update friends" it's suppose to go to the second control and check if we selected male or female and according to that to update the checkedlistbox in the first user control with friends by gender type by what was selected on the second control.
Basically I want to raise an event every time the button on the first control selected then to get the data from the second control to the first control.
Is it possible to do so between two controls who are inside a form and are different controls?
Any help will be appriciated.
Thanks.
To do this "correctly," you would want to use something like the MVC architecture. It's definitely a lot more work initially to understand and implement but is very useful to know if you plan on doing any serious UI application development. Even if you don't go all the way with it, the concepts are useful to help design even "quick and dirty" applications.
Define your data model without thinking in terms of the UI, e.g.:
internal enum Gender
{
Male,
Female
}
internal class Person
{
public Gender Gender { get; set; }
public string Name { get; set; }
}
// . . .
// Populate the list of people
List<Person> allPeople = new List<Person>();
allPeople.Add(new Person() { Gender = Gender.Male, Name = "Xxx Yyy" });
allPeople.Add(new Person() { Gender = Gender.Female, Name = "Www Zzz" });
// . . .
For the view portion, you would typically use data binding on the UI controls so that the controls will automically reflect changes to the underlying data. However, this can get difficult especially if you are not using a database-like model (e.g. System.Data.DataSet). You may opt to "manually" update the data in the controls which might be fine in a small app.
The controller is the portion that uses the UI events and makes changes to the model, which may then be reflected as changes in the view.
internal class Controller
{
private Gender selectedGender;
private List<Person> allPeople;
private List<Person> friends;
public Controller(IEnumerable<Person> allPeople)
{
this.allPeople = new List<Person>(allPeople);
this.friends = new List<Person>();
}
public void BindData(/* control here */)
{
// Code would go here to set up the data binding between
// the friends list and the list box control
}
// Event subscriber for CheckedListBox.SelectedIndexChanged
public void OnGenderSelected(object sender, EventArgs e)
{
CheckedListBox listBox = (CheckedListBox)sender;
this.selectedGender = /* get selected gender from list box here */;
}
// Event subscriber for Button.Click
public void OnUpdateFriends(object sender, EventArgs e)
{
this.friends.AddRange(
from p in this.allPeople
where p.Gender == this.selectedGender
select p);
// If you use data binding, you would need to ensure a
// data update event is raised to inform the control
// that it needs to update its view.
}
}
// . . .
// On initialization, you'll need to set up the event handlers, etc.
updateFriendsButton.Click += controller.OnUpdateFriends;
genderCheckedListBox.SelectedIndexChanged += controller.OnGenderSelected;
controller.BindData(friendsListBox);
// . . .
Basically, I recommend not having controls talk directly, but rather through a controller-like class as above which has knowledge of the data model and the other controls in the view.
Of course it's possible: you need to make the link between the 2 controls in the form.
Just declare an event 'ButtonClicked' in control #1
Then make a public method 'PerformsClick' on the control #2
And in the form, in the constructor, after the call to InitializeComponent, link the event from the control #1 to the method to the control #2:
control1.ButtonClicked += delegate(sender, e) {
control2.PerformsClick();
};
(I type on the fly to give you an idea, it'll surely not compile)
If you want to pass any data, just add parameters in the PerformsClick method.