C# listbox add data from another form - c#

I'm a C# student and I'm a little stuck at on my midterm project.
I dropped my project and spec here: https://www.dropbox.com/sh/eo5ishsvz4vn6uz/CE3F4nvgDf
If you run the program, it will come to the last area I left off at..
private void btnAddScore_Click(object sender, EventArgs e)
{
for (int i = 0; i < 3; i++)
{
tempScore = Convert.ToDecimal(txtScore.Text);
Form1.scoreList = tempScore; (was Form1.scoreList[i] = tempScore;)
}
txtScoresList.Text += Convert.ToString(tempScore) + " ";
}
There's a main form, a secondary add form, and a third and fourth form, all the controls are in place, just the wiring is what's left over.
(1) In the above code, there are supposed to be 3 scores passed to the main form, which, along with a student name string, are to populate the ListBox on the main form. I can't figure out how to access that ListBox, anytime I type "listStudents" nothing happens.
(2) I'm also not sure how to limit an input of only 3 scores when I'm clicking the "add" button 1 time, which means I know my for loop is probably completely wrong. I don't know if I should save those scores to an array, list, or individual vars, being that it can be 3 (or more, but 3 is fine) scores.
(3) When I hit "OK" on the AddNewStudent form, do I write my code there to populate the main form ListBox, or does it go in the main form?
Update:
private void Form1_Load(object sender, EventArgs e)
{
lbStudents.Items.Clear();
//something like
foreach (decimal i in scoreList2)
{
scoreList = scoreList2.ToString(); //gives me a cannot implicitly convert error
}
lbStudents.Items.Add(tempInfo1 + " " + scoreList2);
}
//I want the listbox to populate like "Name - |100| |90| |80|"
This code seems to me, to be correct, for getting the ListBox populated, but I'm unsure of how to add the entire contents of the list to a string, and then add that to the listbox.

This will get your code building and running.
Change the following declaration in form1
public static decimal[] scoreList = new decimal[3];
to
public static List<decimal> scoreList = new List<decimal>();
and update your btnAddScore_Click handler to
//save scores to temp static var, populate noread txtbox txtScoresList with scores
for (int i = 0; i < 3; i++)
{
//save score to static var for trans-form data sending
tempScore = Convert.ToDecimal(txtScore.Text);
Form1.scoreList.Add(tempScore);
}
The rest is not too difficult, you should be able to work it out.

Related

How to display a list inside another list in a Winfoms DataRepeater

I am using C# Windows Forms and a codefirst database (Visual Studio 2013 Ultimate).
Is it possible to display a list inside another list in Windows Forms? (The emphasis is on -displaying- the data).
Please see this project as an example: https://postimg.cc/image/inunj8pxh/
I usually display a list with powerpacks´ datarepeater. For example when an order is placed by a customer, I can display the orderId, customerEmail, customerName etc. of the list of orders.
However, each order includes many different items. So far, I am not able to display any elements of the child-list (items) inside each element the datarepeater, where the parent-list (orders) is shown. The foreign-key of each item is the orderId, and the foreign-key of the order is the list of items (relationship order...items is 1..n).
I found the solution! It took me a while to figure out how to gain control over datarepeater items. Reading across many other forums and tutorials, I gradually worked my way through. Find in the screenshot my complete project:
http://i.stack.imgur.com/jFa7G.png
Any improvements in the code are more than welcome. Since I am quite new to the whole programming world, my code may not be optimized and the use of vocabulary may sometimes be inaccurate.
Here you find the code of my Form1:
namespace list_inside_list
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
protected override void OnLoad(EventArgs e)
{
//First we load the list of Orders to datarepeater1
Program.CompanyContext _context = new Program.CompanyContext();
List<list_inside_list.Program.Order> listOrders = _context.Order.ToList();
program_OrderBindingSource1.DataSource = listOrders;
//I don´t know why, but we need to load the list of items as well, although we never use the listItems variable
List<list_inside_list.Program.Item> listItems = _context.Item.ToList();
/*
* 1. We will loop through all the datarepater1 items (which is fed with listOrders)
* 2. We assign currItem as datarepeater1.CurrentItem in order to "select" the current item at index j,
* although we will never user currItem
* 3. We tell the program that of the current datarepeater item we want use the current Order object
* 4. We go through each of the currentOrder.items and print the itemName
*
*/
DataRepeaterItem currItem = new DataRepeaterItem();
for (int j = 0; j < this.dataRepeater1.ItemCount; j++)
{
this.dataRepeater1.CurrentItemIndex = j;
currItem = dataRepeater1.CurrentItem;
var currentOrder = (list_inside_list.Program.Order)program_OrderBindingSource1.Current;
foreach (var item in currentOrder.items)
{
dataRepeater1.CurrentItem.Controls["richTextBox1"].Text
= dataRepeater1.CurrentItem.Controls["richTextBox1"].Text + item.itemName + "\n";
}
}
}
}
}

How can I clear textboxes so submit button can be re-used?

I am making a program for school in C#, and its purpose is to allow the user to enter film data, which it then puts into an object for that film. It will also include other functionality such as the user being able to search for a film (it says I have to make 3 film objects and store them in an array all being input by the user).
I have created the first part of the Windows Forms application and it is a screen that gets all the input from the user like the name, director, rating, etc... and there is a submit button which creates the object. Is there a way, without creating a new form, to use the same screen and clear the textboxes so that when the submit button is clicked again it creates a NEW OBJECT like 'film2'?
Here is my code for the submit button:
private void button1_Click(object sender, EventArgs e)
{
int year = Convert.ToInt32(dBox_year.Text);
Film film1 = new Film(tbox_name.Text, tbox_director.Text, tbox_actor1.Text, tbox_actor2.Text, year, tbox_rating.Text);
filmArray[0] = film1;
}
So, you see how I would like to have the textboxes on the main screen clear themselves, and reuse the same screen but only it would be 'Film film2 = ...' etc.
This is not an assesed piece and we haven't covered this in class yet so I have tried.
private void button1_Click(object sender, EventArgs e)
{
int year = Convert.ToInt32(dBox_year.Text);
Film film1 = new Film(tbox_name.Text, tbox_director.Text, tbox_actor1.Text, tbox_actor2.Text, year, tbox_rating.Text);
filmArray[0] = film1;
//clearing after adding to array
//or you can just use .Clear() method
tbox_name.Text = String.Empty;
tbox_director.Text = String.Empty;
tbox_actor1.Text = String.Empty;
tbox_actor2.Text = String.Empty;
tbox_rating.Text = String.Empty;
}
tbox_name.Clear() - Clears all text from the text box control.(Inherited from TextBoxBase.)
You could use a List instead of an Array, declared at form level:
private List<Film> filmList = new List<Film>();
Then your button click even would look like
private void button1_Click(object sender, EventArgs e)
{
int year = Convert.ToInt32(dBox_year.Text);
filmList.Add(new Film(tbox_name.Text, tbox_director.Text, tbox_actor1.Text, tbox_actor2.Text, year, tbox_rating.Text));
tbox_name.Text = string.Empty;
tbox_director.Text = string.Empty;
tbox_actor1.Text = string.Empty;
tbox_actor2.Text = string.Empty;
tbox_rating.Text = string.Empty;
dBox_year.Text = string.Empty;
}
Here you're creating a new Film object and adding it straight away to the list of films, and then clearing the text boxes afterwards.
If there's a specific reason you need an array, then you can always later do
filmList.ToArray()
Hope this helps!
When Submit button is clicked you want to add the object at the end of the array, not put it at the first position.So you will need an extra variable named, let say, filmCount, which you initialize with 0 and increment on each submit.
Film film1 = new Film(tbox_name.Text, tbox_director.Text, tbox_actor1.Text, tbox_actor2.Text, year, tbox_rating.Text);
filmArray[filmCount++] = film1;
then you clear the texboxes
foreach(TextBox TB in this.Controls)
{
TB.Text = "";
}

Referencing a dynamically created control in a new TabPage

newbie programmer here after hours of searching has left me stumped.
I'm having trouble with referencing a control inside a tab created at RunTime with a button press. Basically what I have is a tabletop RPG calculator, using a Windows Form, that has a tabControl holding tab pages, with each tab page holding user-inputted stats for that individual enemy to be used in calculations.
The problem is that I want the user to be able to click a button to generate a new enemy tab page. Here is my code for generating an enemy tab page with a TextBox.
int enemyNumber = 0;
// Creates a new Enemy Tab
private void button2_Click_1(object sender, EventArgs e)
{
// Create a new TabPage
var newTabPage = new TabPage()
{
Text = "Enemy " + enemyNumber,
};
// Add Enemy Name Box
var newEnemyNameBox = new TextBox()
{
Name = "enemyNameBox" + enemyNumber,
Text = "",
Location = new Point(127, 11),
Size = new Size(133, 20)
};
// Add the controls to the new Enemy tab
newTabPage.Controls.Add(newEnemyNameBox);
// Add the TabPage to the TabControl
tabControl1.TabPages.Add(newTabPage);
// Increases the enemy's "reference number" by 1
// So that enemy tabs will be generated in order enemyTab0, enemyTab1, etc.
enemyNumber += 1;
}
This all works nicely. Unfortunately, after this point things have gotten ugly. I need to reference that TextBox named "enemyNameBox" + enemyNumber, and I'm not sure how to do so.
What I did was create "archVariables" to store the values from whatever enemy tab is selected, then use the appropriate archVariable in the program's calculations. IE: archEnemyName. The idea is that whatever tab the user is currently selected on (determined via SelectedIndex) the TextBox from that page will be used for the program's output.
Here are the two things I've tried after researching the matter:
// Attempt 1
private void defendCalcButton_Click(object sender, EventArgs e)
{
for (int i = 0; i < tabControl1.SelectedIndex; i++)
{
archEnemyNameBox = ((TextBox)Controls["enemyNameBox" + i]).Text;
}
}
This code simply throws a NullReferenceException when I press the button. So after researching more I tried this:
// Attempt 2
private void defendCalcButton_Click(object sender, EventArgs e)
{
for (int i = 0; i < tabControl1.SelectedIndex; i++)
{
TextBox tb2 = new TextBox();
tb2 = ((TextBox)(enemyTab.Controls.Find("enemyNameBox" + i, true)));
archEnemyNameBox = tb2.Text;
}
}
This time I got an Error: Cannot convert type 'System.Windows.Forms.Control[]' to 'System.Windows.Forms.TextBox'
I feel like the second method I have here is probably closer to the correct way to do this, but apparently I'm still not getting it right. I've learned a lot by searching the information on stackoverflow and msdn.microsoft but nothing has gotten me past this problem.
Any help would be appreciated.
basically the problem with your second attemp is that enemyTab.Controls.Find("enemyNameBox" + i, true) returns an array of Controls Control[] and you're trying to convert that to a Control here is the problem, you should get the first control in that array and then convert it to a Control so it should be like this:
private void defendCalcButton_Click(object sender, EventArgs e)
{
for (int i = 0; i < tabControl1.SelectedIndex; i++)
{
TextBox tb2 = new TextBox();
tb2 = ((TextBox)(enemyTab.Controls.Find("enemyNameBox" + i, true)[0]));
archEnemyNameBox = tb2.Text;
}
}
but it is not the BestWay to do so it seems that everytime a user adds a new tabPage it will have the same Controls right? so why not create an userControl with any Control you have on your TabPage? so when you press the user press to add a new tab your code should be like so:
private void CreateNewEnemyTab()
{
var newTabPage = new TabPage()
{
Text = "Enemy " + enemyNumber,
};
EnemyTabUserControl enemyTab = new EnemyTabUserControl(enemyNumber);
here the EnemyTabUserControl should have all the components you need;
newTabPage.Controls.Add(enemyTab);
tabControl1.TabPages.Add(newTabPage);
}
and the code to bring the TextBox from the current tab could be as follow (you are going to need to reference LINQ)
using System.Linq;
//First Lets create this property, it should return the selected EnemyTabUserControl inside the tabControl
public EnemyTabUserControl CurrentTab {
get {
return tabControl1.SelectedTab.Controls.OfType<EnemyTabUserControl>().First();
}
}
// then if we make the textbox you want to reference from outside the code we can do this
CurrentTab.NameOfTheTextBox;
Patrick has solved your fundamental problem, but I don't think you need the loop in there at all. Here I've broken the steps out so you can see what needs to happen a little better:
private void defendCalcButton_Click(object sender, EventArgs e)
{
Control[] matches = this.Controls.Find("enemyNameBox" + tabControl1.SelectedIndex.ToString(), true);
if (matches.Length > 0 && matches[0] is TextBox)
{
TextBox tb = (TextBox)matches[0];
archEnemyNameBox = tb.Text;
}
}

Road Name windows form application

I will sound like absolutely a noob, but I am so stressed out that I am not able to do any research properly.
Basically I got 127 road names in a list, and I want to display them one by one in a random sequence in a label and I will answer them if its right one increment to green box if its wrong then increment to yellow box but at same time it will display me right answer in a label and then on pressing submit button it will take me to next road name, here is what I have done until now,
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
RL = RoadLocationNames();
i = 1;
red = 1;
y = 1;
}
List<KeyValuePair<string, string>> RL;
int i,red, y;
private void button1_Click(object sender, EventArgs e)
{
Random random = new Random();
int r = random.Next(RL.Count);
lbLocation.Text = RL.ElementAt(r).Key;
if (tbRoad.Text.ToLower() == RL.ElementAt(r).Value.ToLower())
{
Green.Text = i.ToString();
i++;
RL.Remove(RL.ElementAt(r));
}
else
{
label3.Text = RL.ElementAt(r).Value.ToString();
Red.Text = i.ToString();
i++;
}
Yellow.Text = y.ToString();
y++;
}
public List<KeyValuePair<string, string>> RoadLocationNames()
{
List<KeyValuePair<string, string>> RLNs = new List<KeyValuePair<string,string>>();
RLNs.Add(new KeyValuePair<string, string>("Road Name", "Location Name"));
return RLNs;
}
Now My internet is so slow that I barely can upload any screenshot of my form but I will try to.. I got exam tomorrow and I want to do preparation using this app, but I am not sure about,
How to display a road name instead of (road name and its answer which is what my code is doing now) it could be because I am doing everything in buttton submit, I need help with logic and code (sorry but am in rush)
Yes, it's because you're doing everything in your submit. I suggest you split your code into the following:
Initialisation - create the list of road names and locations, then run setup (next step).
Setup - Clear the user's current answer, pick a road name/location pair randomly and display the question part on the form.
User submission - check answer, increment appropriate counter, if the answer is right run setup again, otherwise display what the answer should have been.
Initialisation can be done in your form constructor. Setup should be a private method. User submission should be your click handler.
(It looks like you're incrementing i for both right and wrong answers which is probably incorrect. This is why you pick better variable names than a single letter to make mistakes like that more obvious.)

I need to know how to take the selected item of a comboBox and make it appear on a windows form application?

I have a windows form application with a ComboBox on it and I have some strings in the box. I need to know how when I select one of the strings and press my create button, how can i make that name show up on another windows form application in the panel I created.
Here is the code for adding a customer
public partial class AddOrderForm : Form
{
private SalesForm parent;
public AddOrderForm(SalesForm s)
{
InitializeComponent();
parent = s;
Customer[] allCusts = parent.data.getAllCustomers();
for (int i = 0; i < allCusts.Length; i++)
{
Text = allCusts[i].getName();
newCustomerDropDown.Items.Add(Text);
newCustomerDropDown.Text = Text;
newCustomerDropDown.SelectedIndex = 0;
}
now when i click the create order button I want the information above to be labeled on my other windows form application.
private void newOrderButton_Click(object sender, EventArgs e)
{
//get the info from the text boxes
int Index = newCustomerDropDown.SelectedIndex;
Customer newCustomer = parent.data.getCustomerAtIndex(Index);
//make a new order that holds that info
Order brandSpankingNewOrder = new Order(newCustomer);
//add the order to the data manager
parent.data.addOrder(brandSpankingNewOrder);
//tell daddy to reload his orders
parent.loadOrders();
//close myself
this.Dispose();
}
The context is not very clear to me, but if I got it right, you open an instance of AddOrderForm from an instance of SalesForm, and when you click newOrderButton you want to update something on SalesForm with data from AddOrderForm.
If this is the case, there are many ways to obtain it, but maybe the one that requires the fewer changes to your code is this one (even if I don't like it too much).
Make the controls you need to modify in SalesForm public or at least internal (look at the Modifiers property in the Design section of the properties for the controls). This will allow you to write something like this (supposing customerTxt is a TextBox in SalesForm):
parent.customerTxt.Text = newCustomerDropDown.SelectedItem.Text;

Categories