I am having problems getting the items from my list into a textbox. I’m using Windows forms in Visual Studio.
I have one form with some textboxes and put the inputs to a list. The list contains customers and the user gives the customer an id from one of the textboxes. Now I want to get all the items from the list to the next form.
I have the list in a public class:
public class myClassCustomer
{
public List<customerInformation> cusInformation = new List<customerInformation>();
public class customerInformation
{
public string customerId { get; set; }
public string phoneNumber { get; set; }
public string adress { get; set; }
}
And the code for saving the inputs in form1:
myClassCustomer myClassCustomer = new myClassCustomer()
customers.cusInformation.Add(new myProject.myClassCustomer.customerInformation
{
customerId = txtCustomerId.Text,
phoneNumber = txtPhonenumber.Text,
adress = txtAdress.Text
});
Now in form2 this is what I have written so far:
public form2()
{
InitializeComponent();
myClassCustomer myClassCustomer = new myClassCustomer();
}
Does anyone know how to get all the items from the list?
I'm presuming that the question boils down to how to "get all of the items from the list to the next form", rather than the title suggests "get items from list by id".
The question "Anyone knows how to get all the items from the list?" is a bit tautological because the list already is all of the items.
So I am going to focus on answering your question about the list items being available to the next form. I presume that "Customers" is essentially just a List, and if it isn't, you should probably consider using that instead of a homebrew list class unless you have a very specific requirement otherwise. At the very least, I am hoping that the customers class implements the IEnumerable interface.
In order for this other form to be able to access your list of customers, you need to be making that information available somehow: for instance, you could change the other form's constructor to require a list of customers. Then, when this original form invokes the second form, it must pass in that list it has presumably populated as a parameter.
There are a few other ways this information could be propagated around your application but it sounds like you're just at a beginner level, so the method given above is probably the simplest.
Perhaps you could clarify your question if this does not answer it.
Edit: Some of your own edits have changed the code I was commenting on. It now appears that you're not after a list, but the advice is the same; instead of passing a List, you're just passing a myClassCustomer.
Just define a public property in your form1
public List<customerInformation> AllCustomers
{
get { return yourList; }
}
When opening your Form2 from Form1 use this code:
Form2 f2 = new Form2();
f2.Show(this);
Then you can access your customers from Form2:
var myCustomerList = ((Form1)Owner).AllCustomers;
Related
I am trying to fill a comboBox and a secondary form from a separate class file and I think I have the basics wrong.
The following is shortened to show the bones of what I have and what I think I may be doing wrong. I am not sure if I should be using List<> to populate the comboBox or an Array and suspect in either case my method declaraction is wrong and I cannot find a reference to the comboBox to populate from within the foreach loop.
OK the program.cs for my settings Form. This is not the main form but is the one I am looking to populate when a user select the comboBox.
Program.cs
class Settings
{
public partial class Settings : Form
{
// a bunch of String declarations used throughout
public Settings()
{
InitializeComponent();
}
}
}
The method within a class in a separate file is
Functions.cs
class functions
//This is a separate class to the Settings Form but same namespace.
{
//some global variables here
public string getDomain(string webURL)
{
//more variable declarations
//webURL is a value from the Settings Form
//code to send query to website, get the response and filter the response.
//This is the response filter
foreach (XmlNode node in xmlDoc.SelectNodes("//DAV:domains/DAV:domain", nsmgr))
{
strNode = node.InnerText;
responseString += strNode + " ";
list.Add(strNode);
//I would like to simply Add.Items(strNode) to the Settings.Form.cbxDomains but not as simple as this.
}
//this returns all the correct information as a space separated string.
return responseString;
}
}
From Update UI from a different thread in a different class
I thinks there are 2 things I should do.
1. change the form initialisation from InitilizeComponents() to
settingsWindow = new MyForm();
Application.Run(form);
Then simply call Settings.settingsWindow.cbxDomain.Add>items(responseString);
But do I also need to change the actual method to something like
public void List<String> getDomain(string webURL)
I am so confused. Most examples show it the other way of updating the class from the combo not the other way and some say create it as an array.
I actually think it could even be trimmed down further into one or 2 lines instead of the foreach, but that is way beyond my skillset at this time.
Here is how you could populate your combobox from another form.
I will use example since I do not know you code structure but you will get the point.
public class User //Custom generic class
{
public int _Id { get; set; }
public string _Name { get; set; }
}
public class Functions
{
public static List<User> PopulateComboboxWithUsers()
{
List<User> list = new List<User>();
foreach(var something in somethingBig) //You can change this if you re reading form XML with it's variables or something else
{
list.Add(new User { _Id = something.Id, _Name = something.Name };
}
return list;
}
}
public class Settings
{
public Settings()
{
InitializeComponents();
comboBox1.DataSource = Functions.PopulateComboboxWithUser();
comboBox1.DisplayMember = "_Name";
comboBox1.ValueMember = "_Id";
}
}
Other approach is to do the same function expect you will pass comboBox to it and you will do assigning inside it but I think this is more flexible.
I hope you can help out a fellow programmer. Basically, I want the user input from the Rich Text Box (taskNameRTB) to be assigned to the taskName; string variable in my class taskStructure which is in form1 shown below:
public partial class Form1 : Form
{
public class taskStructure
{
public string taskName;
public string taskDescription;
public int Priority;
public string dateAndTime;
}
public List<taskStructure> TasksArray = new List<taskStructure>(); //Declared a list data structure
In my second form which is where the user enters everything related to the task, I want to send this information to the list after the 'Create Task' button has been clicked:
private void createTaskBtn_Click(object sender, EventArgs e)
{
Form1 welcomeForm = new Form1();
welcomeForm.TasksArray[0].taskName = taskNameRTB.Text;
welcomeForm.TasksArray[0].taskDescription = taskDescRTB.Text;
}
However, when I do this I get a ArgumentOutOfRangeException and I do not understand why. I have also tried these:
welcomeForm.TasksArray[0].Add(taskDescRTB.Text);
welcomeForm.TasksArray.Insert(0, taskNameRTB.Text);
welcomeForm.TasksArray.Add(taskDescRTB.Text);
taskNameRTB.Text = welcomeForm.TasksArray[0].taskName;
But the ones that run come up with the same error ArgumentOutOfRangeException and some of them don't work, such as:
welcomeForm.TasksArray[0].Add(taskDescRTB.Text);
I'm aware that the list has not been initialized, but how can I initialize it when it doesn't allow me to initialize it with user input...
Any light you can shed on this will be really helpful
Kind Regards,
Kieran
You need to add a new taskStructrue to the list.
welcomeForm.TasksArray.Add(new taskStructure
{
taskName = taskDescRTB.Text,
taskDescription = taskDescRTB.Text
});
But personally I'd rewrite that class to follow naming conventions and to use properties instead of public fields.
public class TaskStructure
{
public string TaskName { get; set; }
public string TaskDescription { get; set; }
public int Priority { get; set; }
public string DateAndTime { get; set; }
}
have you tried
welcomeForm.TasksArray.Add(new taskStructure(taskDescRTB.Text));
I don't know what taskStructure is, but you need to fill TasksArray with types of it.
Your TaskStructure is a class, and you are putting all TaskStructure objects into a list,
public List<taskStructure> TasksArray = new List<taskStructure>(); //Declared a list data structure
Does your Form1() have a constructor that calls InitializeComponents()?
If so, you could try adding TasksArray = new List<taskStructure>() right below InitializeComponents(), because it looks like you're trying to access the list data structure that hasn't been initialized with new.
Alternatively
As another user noted, you can create a constructor class for TaskStructure like this:
public TaskStructure(RTB rtb1, rtb2, rtb3) //where RTB is the rich text box type
{
taskName = rtb1.text;
taskDescription = rtb2.text;
//and so on.
}
Then you can do TaskArray.add(new TaskStruture(rtb1,rtb2,rtb3).
Thrid Edit
Just realized your TaskArray is actually a List, which in C# (and Java), you cannot access it with an index like TaskArray[0], you have to use getter and setter methods, which in this case is TaskArray.add(), and TaskArray.get(0), you're getting ArgumentOutOfRangeException because you're trying to access a List using square indexes like this --> [0]. You can actually access a list doing list1, as pointed out by another user.
Here's a good tutorial on C# lists, by DotNetPerls
I'm making a program that catalogs the names of the people I add in a listbox and save all the content to a file when you close the program.
Each line of the file is for a person:
Tommy
Marco
James
Dylan
When the program starts, the file data is loaded and add the names to listbox.
All this works great, but now I'm having trouble making something else.
Each person on the list need a variable to indicate whether it has paid and I want to save this variable together with his name on the file.
For this, I have:
bool paid;
private void checkbox_Paid_CheckedChanged(object sender, EventArgs e)
{
paid = true;
}
I have only one checkbox, and it needs to differ from each person in the listbox, according to the selected in the event:
private void listDOF_SelectedIndexChanged(object sender, EventArgs e)
{
}
But I do not know how to write this bool in the file for each person, save to the file together with name and load it.
I've tried something like:
foreach(string purchasers in listDOF.Items)
{
arq.WriteLine(purchases, paid);
}
Obviously this do not worked, I do not know how to assign the bool for each one of the purchasers and write it in the file.
I'm using .NET 4.5 in a WFA.
Thanks all in advance, if I able to do this, I will give a big step toward the knowledge.
First of all I would store the persons in a list in the application otherwise you will only have one bool for all the persons in the application and everyone will be set as payed or not payed.
public class Person
{
public string Name { get; set; }
public bool Payed { get; set; }
}
public List<Person> Persons { get; set; }
As simple way is to save it in a SCV file. Semicolons between fields and new row per post
Tommy; true
Marco; true
Then save like this
foreach(var person in Persons)
{
arq.WrtieLine("{0};{1}", person.Name, person.Payed);
}
I believe that this is a good case to turn your text file into JSON.
For example:
[
{ name: "Tom", hasPaid: true },
{ name: "Matias", hasPaid: false } // Urgh!
]
And In C# you can build up this JSON using anonymous objects:
List<object> people = new List<object>();
people.Add(new { Name = "Tom", HasPaid = true });
Finally, you can serialize to JSON using JSON.NET:
File.WriteAllText(#"C:\myfile.json", JsonConvert.SerializeObject(people));
...or deserialize it:
List<object> people = JsonConvert.DeserializeObject<List<object>>(File.ReadAllText(#"C:\myfile.json"));
Update
Maybe you should use an concrete class rather than an anoymous object, because the later is inmutable and you're going to get in troubles if you need to data-bind the object list to the whole ListBox.
You can declare a simple class like this:
public class Person
{
public string Name { get; set; }
public bool HasPaid { get; set; }
}
...add persons this way:
List<Person> people = new List<Person>();
Person person = new Person();
person.Name = "Tom";
person.HasPaid = true;
people.Add(person);
File.WriteAllText(#"C:\myfile.json", JsonConvert.SerializeObject(people));
And when it comes to deserializing the whole JSON array:
List<Person> people = JsonConvert.DeserializeObject<List<Person>(File.ReadAllText(#"C:\myfile.json"));
Update 2
It seems like you don't know you can bind a list to Windows Forms controls. See for example the following MSDN article.
Instead of List<T> you can use BindingList<T>. Check this CodeProject guide.
This way, when you add an item to the whole BindingList<T> the ListBox control will be automatically populated. If you remove one, it will also dissapear from the UI.
Both Windows Forms and Windows Presentation Foundation are powerful and productive if you leverage data-binding (also in Web development, say KnockoutJS!).
I am writing a program for customizing drinks. The program lets the user select a size, flavor, topping, and quantity. The user then presses the button "Add drink to order" and a message pops up "Do you want to customize another drink to add to your order? Yes, No" My question is how do you save the first customized drink to print in the receipt along with the second drink? When clearing the form the data is lost correct?
Your program has to save the data. This can be into a database, or into a collection. I don't think you are using a database yet, so a collection is the best way.
Create a class that has a property for each type of value. Then make a list of those, populated with values.
First build an object that represents the order
public class DrinkOrder
{
public Object Size { get; set; }
public Object Flavor { get; set; }
public Object Topping { get; set; }
public Object Quantity { get; set; }
}
Note: I use the vague Object type because I don't know how you're representing those field values
Then add a list to your form that retains the past/future "orders"
List<DrinkOrder> Orders = new List<DrinkOrder>();
Then, when they click add, populate the object and add it to the list of orders.
private void btnPlaceOrder_Click(object sender, EventArgs e)
{
/* ... */
this.Orders.Add(new DrinkOrder
{
Size = this.SizeControl.Value,
Flavor = this.FlavorControl.Value,
Toppings = this.ToppingControl.value
Quantity = this.QuantityControl.Value
});
/* ... */
}
Then, you can clear the forms (if desired) and be ready to do it all over again.
Once they're done placing orders, you now have a list (Orders) you can reference as a "shopping cart".
Perhaps you could put the data somewhere? Like an array?
You can use Data Binding for this, it's easy and saves multiple data. You can read more about it here
i'm having trouble getting a clear answer for this.
I have a Static class (DataHolder) that holds a static list with a complex type (CustomerName and CustomerID properties).
I want to bind it to a ListBox in WPF but add another item that will have the word "All" for future drag and drop capablilities.
Anyone?
Create a ViewModel Class you can databind to! The ViewModel can reference the static class and copy the items to its own collection and add the all item to it.
Like this
public class YourViewModel
{
public virtual ObservableCollection<YourComplexType> YourCollection
{
get
{
var list = new ObservableCollection<YourComplexType>(YourStaticClass.YourList);
var allEntity = new YourComplexType();
allEntity.Name = "all";
allEntity.Id = 0;
list.Insert(0, allEntity);
return list;
}
}
}
Note, sometimes, you need empty Items. Since WPF can't databind to null values you need to use the same approach to handle it. The empty business entity has been a best practice for it. Just google it.
That "All" item has to be part of the list you bind your ListBox against. Natuarally you can not add that item to the DataHolder list because it holds items of type Customer (or similar). You could of course add a "magic" Customer that always acts as the "All" item but that is for obvious reasons a serious case of design smell (it is a list of Customers after all).
What you could do, is to not bind against the DataHolder list directly but introduce a wrapper. This wrapper would be your ViewModel. You would bind your ListBox agains a list of CustomerListItemViewModel that represents either a Customer or the "All" item.
CustomerViewModel
{
string Id { get; private set; }
string Name { get; set; }
public static readonly CustomerViewModel All { get; private set; }
static CustomerViewModel()
{
// set up the one and only "All" item
All = new CustomerViewModel();
All.Name = ResourceStrings.All;
}
private CustomerViewModel()
{
}
public CustomerViewModel(Customer actualCustomer)
{
this.Name = actualCustomer.Name;
this.Id = actualCustomer.Id;
}
}
someOtherViewModel.Customers = new ObservableCollection<CustomerViewModel>();
// add all the wrapping CustomerViewModel instances to the collection
someOtherViewModel.Customers.Add(CustomerViewModel.All);
And then in your Drag&Drop code somewhere in the ViewModel:
if(tragetCustomerViewModelItem = CustomerViewModel.All)
{
// something was dropped to the "All" item
}
I might have just introduced you to the benefits of MVVM in WPF. It saves you a lot of hassle in the long run.
If you use binding than the data provided as the source has to hold all of the items, ie. you can't databind and then add another item to the list.
You should add the "All" item to the DataHolder collection, and handle the 'All' item separately in your code.