I'm new to C# and I just have a quick question about adding to an array list. I have an arraylist which shows some details about different books (Name, Genre, Author and Year Published). How can I make it so that a user can input all these values (name, genre, etc) into multiple textboxes and then click a button to add all the details as a new book in the list?
Below is my code so far:
namespace LibraryBooks
{
public partial class Form1 : Form
{
List<Object> library = new List<Object>();
int current = 0;
public Form1()
{
InitializeComponent();
InitializeArrayList();
DisplayData();
}
public void DisplayData()
{
Books b = (Books)library[current];
textBox1.Text = "" + b.readTitle();
textBox2.Text = "" + b.readGenre();
textBox3.Text = "" + b.readAuthor();
textBox4.Text = "" + b.readYearPublished();
}
public void InitializeArrayList()
{
library.Add(new Books("The Hunger Games", "Adventure", "Suzanne Collins", "2008"));
library.Add(new Books("Gone Girl", "Thriller", "Gillian Flynn", "2014"));
library.Add(new Books("A Game of Thrones", "Fantasy", "George R.R. Martin", "1996"));
}
private void button5_Click(object sender, EventArgs e)
{
if (movies.Contains(textBox7.Text))
{
textBox1.Text = "";
}
}
}
public class Test92
{
public static void Main(string[] args)
{
Application.Run(new Form1());
}
}
}
I'm not sure how to go about it at all so any ideas would be appreciated.
It's very simple. Create all the textboxes you need for each input, and then in your button_click method, write something along the lines of
library.Add(new Books(textbox1.text, textbox2.text, textbox3.text));
This functions very similarly to what your InitializeArrayList method does, but instead of passing pre-determined text to your Books constructor, it takes in text from the textboxes on your form.
Related
I have a list variable and I created an iterator for it to print out its content. It's working in the console application but when i try to do it using windows form(gui) it doesn't work
PROGRAM.CS
namespace gui
{
static class Program
{
public class studentdata
{
public string id, name, password, academicyear, finishedcourseslist, ipcourseslist;
public int noCoursesF, noCoursesIP;
public List<string> coursesF;
public List<string> coursesIP;
public studentdata()
{
id = "2015123";
password = "Student";
coursesF = new List<string>();
coursesIP = new List<string>();
}
public studentdata(string ID, string NAME, string PASSWORD)
{
id = ID;
}
**public void view_finished_courses()
{
List<string> finished = coursesF;
foreach (string n in finished)
{
finishedcourseslist += n;
}
MessageBox.Show(finishedcourseslist, "Finished courses");
}
public void view_ip_courses()
{
List<string> progress = coursesIP;
foreach (string m in progress)
{
ipcourseslist += m;
}
MessageBox.Show(ipcourseslist, "Finished courses");
}**
}
public class Admin
{
public string name, password;
public Admin()
{
name = "Admin";
password = "Admin";
}
}
//functionssssss
internal static studentdata studentSearch(string IDsearch)
{
FileStream FS = new FileStream("Students.txt", FileMode.Open);
StreamReader SR = new StreamReader(FS);
studentdata std = new studentdata();
while (SR.Peek() != -1)
{
string z = SR.ReadLine();
String[] Fields;
Fields = z.Split(',');
if (IDsearch.CompareTo(Fields[0]) == 0)
{
std.id = Fields[0];
std.password = Fields[1];
std.name = Fields[2];
std.noCoursesF = int.Parse(Fields[3]);
int currentField = 4;
for (int course = 0; course < std.noCoursesF; course++)
{
std.coursesF.Add(Fields[currentField]);
currentField++;
}
std.noCoursesIP = int.Parse(Fields[currentField]);
currentField++;
for (int course = 0; course < std.noCoursesIP; course++)
{
std.coursesIP.Add(Fields[currentField]);
currentField++;
}
std.academicyear = Fields[currentField];
SR.Close();
return std;
}
else continue;
}
SR.Close();
studentdata araf = new studentdata();
return araf;
}
}
FORM.CS
namespace gui
{
public partial class Form3 : Form
{
Program.studentdata student = new Program.studentdata();
public Form3()
{
InitializeComponent();
}
private void label1_Click(object sender, EventArgs e)
{
}
private void button5_Click(object sender, EventArgs e)
{
}
private void button4_Click(object sender, EventArgs e)
{
student.view_finished_courses();
}
private void button6_Click(object sender, EventArgs e)
{
student.view_ip_courses();
}
}
}
The output is an empty message box, I don't know why variable isn't added.
Replace messagebox line with
MessageBox.Show(string.Join(",", coursesF.ToArray()), "Finished courses");
It seems like your code is incomplete. Nowhere in the code which gets executed after you clicked button4 you are adding items to coursesF. It seems that you are adding items in this line: std.coursesF.Add(Fields[currentField]);
This line is in your function studentSearch(IDsearch), the function never gets called.
In this function you got a string z in which all the data of a student is saved (string z = SR.ReadLine()). You must somehow fill this string z. You can use a TextBox in your form and pass the value into the string, use a string from a text file or use the console input(see here: Get input from console into a form).
As you can see the issue is not a one line fix.
I'm writing a name generator, and want to add functionality to add new names and surnames to database, but when I'm trying to print values added after running program, I got whole path. For example: I want to add name John. When generator picks John it's printing Windows.Forms.TextBox, Text:John instead of just name. How can I fix this? Here's the code:
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace NameGen
{
public partial class Form1 : Form
{
public Generate gen = new Generate();
public Form1()
{
InitializeComponent();
}
private void StartGenerate(object sender, EventArgs e)
{
lblWynik.Text = Generate.NameGen() + " " + Generate.SurnameGen();
Console.WriteLine("Generating: " + lblWynik.Text);
}
private void AddName(object sender, EventArgs e)
{
Generate.LName.Add(NameBox.ToString());
Console.WriteLine("Adding new name to index " + NameBox);
NameBox.Clear();
}
private void AddSurname(object sender, EventArgs e)
{
Generate.LSurname.Add(SurnameBox.ToString());
Console.WriteLine("Adding new surname to index " + SurnameBox);
SurnameBox.Clear();
}
}
public class Generate
{
static string[] Name = new string[] { "Hank", "Terrence", "Darin", "Alf" };
static string[] Surname = new string[] { "Cooper", "Trump", "Białkov", "Obama" };
public static List<string> LName = new List<string>();
public static List<string> LSurname = new List<string>();
static Random random = new Random();
public static string NameGen()
{
LName.AddRange(Name);
int NameIndex = random.Next(LName.Count);
return LName[NameIndex];
}
public static string SurnameGen()
{
LSurname.AddRange(Surname);
int NameIndex = random.Next(LSurname.Count);
return LSurname[NameIndex];
}
}
To get the text of a TextBox you should use Text property of TextBox. For example: Generate.LName.Add(NameBox.Text);
Now you are using ToString method of TextBox which returns the type name and the text.
I'm trying to manipulate the properties of a control in my main form via one of my classes.
Basically I'm trying to update a label, I've set it to public like so:
public Label DicerollLabel;
And I'm refering to my main form from my class like this:
private Form1 _mainForm;
When I try to access the label and set a value to it like this:
_mainForm.DicerollLabel.Text = "Hello World!";
I get the following error:
An unhandled exception of type 'System.NullReferenceException' occurred.
My entire code to the two files involed is below:
Main Form:
namespace BettingGame
{
public partial class Form1 : Form
{
private Player _playerOne;
private Player _playerTwo;
private DiceRoller _diceRoller;
private decimal _prizePool;
private Random _random;
public int ProgressBar
{
get {return progressBar1.Value;}
set { progressBar1.Value = value; }
}
public Label DicerollLabel;
public Form1()
{
InitializeComponent();
_playerOne = new Player() {PlayerName = "x", PlayerFunds = 100};
_playerTwo = new Player() {PlayerName = "x", PlayerFunds = 100};
_diceRoller = new DiceRoller();
_random = new Random();
playerOneFundsLabel.Text = "Funds: " + _playerOne.PlayerFunds.ToString(CultureInfo.CurrentCulture) + "$";
playerTwoFundsLabel.Text = "Funds: " + _playerTwo.PlayerFunds.ToString(CultureInfo.CurrentCulture) + "$";
PrizeAmountLabel.Text = "";
diceRollLabel.Text = "";
}
private void button1_Click(object sender, EventArgs e)
{
_playerOne.PlayerBetAmount = (decimal) playerOneBet.Value;
_playerTwo.PlayerBetAmount = (decimal) playerTwoBet.Value;
if (!(_playerOne.PlayerBetAmount <= 0) || !(_playerTwo.PlayerBetAmount <= 0)
&& (_playerOne.PlayerBetAmount > 0) && (_playerTwo.PlayerBetAmount > 0))
{
_prizePool = _playerOne.PlayerBet() + _playerTwo.PlayerBet();
PrizeAmountLabel.Text = _prizePool.ToString(CultureInfo.CurrentCulture);
FormUpdate();
}
else
{
MessageBox.Show("Invalid bets! Bet amount must be greater than 0!");
}
}
private void FormUpdate()
{
playerOneFundsLabel.Text = "Funds: " + _playerOne.PlayerFunds.ToString(CultureInfo.CurrentCulture) + "$";
playerTwoFundsLabel.Text = "Funds: " + _playerTwo.PlayerFunds.ToString(CultureInfo.CurrentCulture) + "$";
}
private void button2_Click(object sender, EventArgs e)
{
//for (int i = 0; i < 45; i++)
//{
// int value = _random.Next(1, 50);
// diceRollLabel.Text = value.ToString();
// diceRollLabel.Update();
// Thread.Sleep(50);
//}
_diceRoller.RollDice();
}
}
}
And the DiceRoller class:
namespace BettingGame
{
class DiceRoller
{
private Random _random = new Random();
private Form1 _mainForm;
public void RollDice()
{
_mainForm.DicerollLabel.Text = "Hello World!";
}
}
What am I doing wrong? Note that I'm only in my second week of programming so I'm still learning!
change your DiceRoller class to define the following constructor:
public DiceRoller(Form1 host) {
_mainForm = host;
}
Then in your Form1 where you create an instance of DiceRoller:
private DiceRoller _diceRoller = new DiceRoller(this);
This is a really terrible design long term. It's definitely code I would expect from a new programmer - so don't feel bad. You're doing fine.
In the future try to think about reusability. By making your DiceRoller dependent on Form1 (and the specific controls in Form1) you are faced with two challenges later on:
1. You can not use DiceRoller in another project (or possibly even in your same project) without modification.
2. If you change any of the controls that DiceRoller depends upon you must also change DiceRoller.
I'll let you think about how you might avoid these issues. I'm sure if you need help with them you'l post another question. :)
You need to have a reference to the Form1 created. This is not named Form1, but within the Form1 you can refer to it using the keyword "this" and you can pass that into a constructor for your DiceRoller class.
class DiceRoller
{
private Random _random = new Random();
private Form1 _mainForm;
public DiceRoller(Form1 f)
{
_mainForm = f;
}
public void RollDice()
{
_mainForm.DicerollLabel.Text = "Hello World!";
}
}
Then you call this within your constructor for Form1:
public Form1()
{
InitializeComponent();
_playerOne = new Player() {PlayerName = "x", PlayerFunds = 100};
_playerTwo = new Player() {PlayerName = "x", PlayerFunds = 100};
_diceRoller = new DiceRoller(this);
....
These are the minimal changes needed to make your code work. However, you might consider other changes such as passing in the label instead of the form.
I have three classes, code provided below.
Network - Add and Remove Phone, Process Calls
Phone1 and Phone2 can call each other when added to the network.
But I am having issue when I am connecting both phone to the network and trying to call phone1 to phone2, it is keep giving me "receiver busy". I have tried to do little debugging and read status of phone2 when calling from phone1 but it returns an empty string (Which should actually return "A", when it is added to the network).
Any help would much appreciated.
-----Networks Class------------------
namespace Demo
{
public partial class network : Form
{
phone1 p1 = new phone1();
phone2 p2 = new phone2();
public network()
{
InitializeComponent();
}
public Boolean numberValidator(int number)
{
Boolean exist = false;
if (comboBox2.Items.Equals(number))
{
exist = true;
}
return exist;
}
public void processCall(int rNumber)
{
if (!numberValidator(rNumber))
{
p1.TextBox1.Clear();
p1.TextBox1.Text = "Not connected";
//MessageBox.Show(p2.returnPhoenStatus());
}
else
{
p1.TextBox1.Clear();
p1.TextBox1.Text = "Call in progress";
p2.receiveCall(1);
p1.setStatus("Busy");
/*
if (p2.btnCallPressStatus())
{
p1.TextBox1.Clear();
p1.TextBox1.Text = "Call initiated";
}*/
}
}
private void button1_Click(object sender, EventArgs e)
{
if (comboBox1.SelectedIndex == 0)
{
p1.Show();
comboBox2.Items.Add(1);
p1.setStatus("A");
}
if (comboBox1.SelectedIndex == 1)
{
p2.Show();
comboBox2.Items.Add(2);
p2.setStatus("A");
}
}
}
}
----------Phone1 Class---------
namespace Demo
{
public partial class phone1 : Form
{
public phone1()
{
InitializeComponent();
}
string status;
public void setStatus(string Status)
{
status = Status;
}
public string returnStatus()
{
return status;
}
public void receiveCall(int callerNumber)
{
setStatus("Busy");
btnCall.Text = "Answer";
textBox1.Text = "Phone " + callerNumber + " Calling.";
}
public void makeCall(int number)
{
phone2 p2 = new phone2();
network net = new network();
MessageBox.Show(p2.returnStatus()); // this line not returing status of phone2
if (p2.returnStatus() == "A")
{
net.processCall(number);
}
else
{
textBox1.Text = "Receiver Busy";
}
}
public TextBox TextBox1
{
get
{
return textBox1;
}
}
private void btnCall_Click(object sender, EventArgs e)
{
string number = textBox1.Text;
int numberInt = Convert.ToInt16(number);
makeCall(numberInt);
}
string phoneNo = "";
private void btn2_Click(object sender, EventArgs e)
{
phoneNo = phoneNo + btn2.Text;
textBox1.Text = phoneNo;
}
}
}
-------------phone2 Class--------------
namespace Demo
{
public partial class phone2 : phone1
{
public phone2()
{
InitializeComponent();
}
}
}
I think you are setting the status of P1 both the times. Check this if condition in button1_Click method in network class. The setStatus should be for P2.
if (comboBox1.SelectedIndex == 1)
{
p2.Show();
comboBox2.Items.Add(2);
p2.setStatus("A");
}
Piyush has the right answer, but I thought I'd add this answer as a handy hint to avoid this kind of error.
Try writing your button1_Click method like this:
private void button1_Click(object sender, EventArgs e)
{
var i = comboBox1.SelectedIndex;
var p = (new [] { p1, p2 })[i]; // Or `var p = i == 0 ? p1 : p2;`
p.Show();
comboBox2.Items.Add(i + 1);
p.setStatus("A");
}
This way you avoid the code duplication and the mistyping that occurred.
Im new to c# and programming
i can make the method Work, but not when i try to call it from my class 'Admin', it think its just a minor problem, but im just stuck ... Again.. No overload for method "opretspejder" takes 0 arguments
any help help i would be glad
Here my class
public class Admin
{
public static void OpretSpejder(string Snavn_txt, string Senavn_txt, string Sa_txt, string Scpr_txt)
{
{
if (!(string.IsNullOrEmpty(Snavn_txt)))
if (!(string.IsNullOrEmpty(Senavn_txt)))
if (!(string.IsNullOrEmpty(Sa_txt)))
if (!(string.IsNullOrEmpty(Scpr_txt)))
{
XmlDocument doc = new XmlDocument();
doc.Load(#"Spejder.xml");
var nodeCount = 0;
using (var reader = XmlReader.Create(#"Spejder.xml"))
{
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element &&
reader.Name == "Spejder")
{
nodeCount++;
}
}
}
nodeCount++;
XmlElement Spejder = doc.CreateElement("Spejder");
Spejder.SetAttribute("ID", nodeCount.ToString());
XmlNode Navn = doc.CreateElement("Navn");
Navn.InnerText = Snavn_txt;
Spejder.AppendChild(Navn);
XmlNode Efternavn = doc.CreateElement("Efternavn");
Efternavn.InnerText = Senavn_txt;
Spejder.AppendChild(Efternavn);
XmlNode Alder = doc.CreateElement("Alder");
Alder.InnerText = Sa_txt;
Spejder.AppendChild(Alder);
XmlNode Cpr = doc.CreateElement("Cpr");
Cpr.InnerText = Scpr_txt;
Spejder.AppendChild(Cpr);
doc.DocumentElement.AppendChild(Spejder);
doc.Save(#"Spejder.xml");
Snavn_txt = String.Empty;
Senavn_txt = String.Empty;
Sa_txt = String.Empty;
Scpr_txt = String.Empty;
// MessageBox.Show("Spejder Oprettet");
}
}
and here is the buttonclick i want to execute my method:
private void button2_Click(object sender, EventArgs e)
{
Admin.OpretSpejder();
}
The declaration of your method says
public static void OpretSpejder(string ..., string ...., string ...., string ....)
but you call it without passing any of the 4 strings required
Admin.OpretSpejder();
Of course the compiler is not happy
It seems that the method OpretSpejder wants to create an XML file with 4 elements and these 4 elements are required because without them the whole block of code is skipped, so you have no alternative than passing the 4 strings required
If you are the author of OpretSpejder then I think that you should know what to pass at the calling point, otherwise you should ask the author of the code what are these four parameters
You've declared OpretSpejder method with 4 mandatory string arguments
(Snavn_txt, Senavn_txt, Sa_txt, Scpr_txt):
public class Admin {
public static void OpretSpejder(string Snavn_txt, string Senavn_txt, string Sa_txt, string Scpr_txt) {
...
So If you want to call this method you should either provide these arguments:
private void button2_Click(object sender, EventArgs e) {
string Snavn_txt = "..."; // <- Put your real values here
string Senavn_txt = "...";
string Sa_txt = "...";
string Scpr_txt = "...";
Admin.OpretSpejder(Snavn_txt, Senavn_txt, Sa_txt, Scpr_txt);
}
or as compiler suggested create an overload version of OpretSpejder with no arguments:
public class Admin {
// New overloaded version
public static void OpretSpejder() {
...
}
// Old version
public static void OpretSpejder(string Snavn_txt, string Senavn_txt, string Sa_txt, string Scpr_txt) {
...
public partial class Form1 : System.Windows.Forms.Form
{
public Form1()
{
InitializeComponent();
}
Admin classAdmin = new Admin();
private void button2_Click(object sender, EventArgs e)
{
classAdmin.OpretSpejder("yourstring1","yourstring2","yourstring3","yourstring4"); //Admin.OpretSpejder();
}
}