How to add text from textbox into a list - c#

I have create a empty list which will get used when the user enters new tracks and my interface has listbox and a texbox and add and remove button.
My aim is to when i add a new item into the listbox same button use the function to add that item to a list rather them just adding to a listbox and not storing it.
trackListbox.Items.Add(newTracktextBox.Text);
List<Songs> NewSongs = newTracktextBox.Text ().ToList(); ; this is not correct
Any different ideas?
class Songs
{
private string trackName;
private int trackLength;
public Songs (string trackName, int trackLength)
{
this.trackName = trackName;
this.trackLength = trackLength;
}
}

Try this
Songs objSong = new Songs(newTracktextBox.Text,0); // define your length instead of 0
List<Songs> NewSongs = new List<Songs>();
NewSongs.Add(objSong);

It's good practice to name the class Song instead of Songs since it will represent only one song.
With adding songs manually to the listBox
private List<Song> SongList;
public Form1()
{
InitializeComponent();
SongList = new List<Song>();
}
private void button1_Click(object sender, EventArgs e)
{
Song song = new Song(newTracktextBox.Text, 100);
SongList.Add(song);
listBox1.Items.Add(song); // The trackName will be shown because we are doing a override on the ToString() in the Song class
}
class Song
{
private string trackName;
private int trackLength;
public Song(string trackName, int trackLength)
{
this.trackName = trackName;
this.trackLength = trackLength;
}
public override string ToString()
{
return trackName;
// Case you want to show more...
// return trackName + ": " + trackLength;
}
}
With automatic binding by using a BindingList<Song>
private BindingList<Song> SongList;
public Form1()
{
InitializeComponent();
// Initialise a new list and bind it to the listbox
SongList = new BindingList<Song>();
listBox1.DataSource = SongList;
}
private void button1_Click(object sender, EventArgs e)
{
// Create a new song and add it to the list,
// the listbox will automatically update accordingly
Song song = new Song(newTracktextBox.Text, 100);
SongList.Add(song);
}
class Song
{
private string trackName;
private int trackLength;
public Song(string trackName, int trackLength)
{
this.trackName = trackName;
this.trackLength = trackLength;
}
public override string ToString()
{
return trackName;
}
}
Result

Your newTracktextBox variable is not an object of type Song.
You should create a new object of type Song with the text that's in newTracktextBox and add the new object to the list

public class Songs{
String TrackName;
int TrackLength;
public Songs(string trackName, int trackLength){
this.TrackName = trackName;
this.TrackLength = trackLength;
}
//methods
}
make a list of songs
List<Songs> NewSongs = new List<Songs>();
add the new song to the list by
int tracklength = 50; // set the tracklength where you need
NewSongs.Add(new Songs(TextBox.Text.ToString(),tracklegnth));
Note that the ToString() method maybe is redudant.
hope i helped

Related

Update data in a listbox from another form

I'm creating a program that maintains student scores. I've created a class called students that stores the data and displays it in a list box. Once the user clicks Add a new form (frmAddStudent) loads that allow them to add the user by name and their scores and display it in the list box in the main form. It also allows the update/delete functions. I can successfully add students to the list and edit them, but when I press the ok button in the update students form I get the error
System.ArgumentOutOfRangeException: 'Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index'
I looked up that this means its thrown when the value of an argument is outside the allowable range of values as defined by the invoked method, but not sure how it applies here. My value I enter when updating is within range.
Source code below
https://github.com/Triptonix/Student.git
frmUpdateStudent.cs
private void UpdateButton_Click_1(object sender, EventArgs e) //open update form for current student
{
Student Form1 = new Student();
Form1.Name = StudentName.Text;
parentForm.UpdateStudent(index, Form1);
Close();
}
Form1.cs
public List<Student> studentList = new List<Student>();
public Student GetStudent(int id) //Get student index
{
return studentList[id];
}
public void UpdateStudentList()
{
students.DataSource = null;
students.DataSource = studentList;
students.DisplayMember = "Name";
}
public bool UpdateStudent(int originalIndex, Student studentToEdit)
{
try
{
Student student = GetStudent(originalIndex); //select index of student
student.Name = studentToEdit.Name; //name of student
studentList.RemoveAt(originalIndex); //remove the student at the index selected
studentList.Insert(originalIndex, student); //insert new student at index.
UpdateStudentList(); //update student list
}
catch { return false; }
return true;
}
Student.cs
public class Student
{
public List<int> Scores = new List<int>();
public string Name { get; set; }
public bool AddScore(int score)
{
try
{
Scores.Add(score);
}
catch { return false; }
return true;
}
public List<int> GetScores()
{
return Scores;
}
public int GetScoreAt(int index)
{
return (int)Scores[index];
}
public int GetScoreTotal()
{
int sum = 0;
foreach (int score in Scores)
{
sum += score;
}
return sum;
}
public int GetScoreCount()
{
return Scores.Count;
}
public int GetScoreAverage()
{
return GetScoreTotal() / GetScoreCount();
}
public void DestroyScores()
{
Scores = new List<int>();
}
}
frmUpdateStudent
public partial class frmUpdateStudent : Form
{
private Form1 parentForm; //main form
private Student studentToEdit; //student list
private int index; //index
public frmUpdateStudent(Form1 parentForm, int index) //update parent form (Form1) with the new student and scores
{
this.parentForm = parentForm;
this.index = index;
studentToEdit = this.parentForm.GetStudent(index);
InitializeComponent();
StudentName.Text = studentToEdit.Name;
UpdateScoreDisplay();
}
public void AddScoreToStudent(int value) //add score to current student and display in the list
{
studentToEdit.AddScore(value);
UpdateScoreDisplay();
}
public void UpdateScoreAtIndex(int id, int value) //update a score selected from the list
{
studentToEdit.GetScores()[id] = value;
UpdateScoreDisplay();
}
public int GetScoreAtIndex(int id) //get the score index
{
return studentToEdit.GetScoreAt(id);
}
private void UpdateScoreDisplay() //update the score display list
{
CurrentScores.DataSource = null;
CurrentScores.DataSource = studentToEdit.GetScores();
}
private void AddScoreButton_Click(object sender, EventArgs e) //open the add score form
{
frmAddScore addScoreForm = new frmAddScore(this);
addScoreForm.Show();
}
private void RemoveScoreButton_Click_1(object sender, EventArgs e) //remove a score from current index and update display list
{
studentToEdit.GetScores().RemoveAt(CurrentScores.SelectedIndex);
UpdateScoreDisplay();
}
private void ClearScoresButton_Click_1(object sender, EventArgs e) //clear all scores
{
studentToEdit.DestroyScores();
UpdateScoreDisplay();
}
private void CloseButton_Click_1(object sender, EventArgs e)
{
Close(); //close form
}
private void UpdateButton_Click_1(object sender, EventArgs e) //open update form for current student
{
Student Form1 = new Student();
Form1.Name = StudentName.Text;
parentForm.UpdateStudent(index, Form1);
Close();
}
private void UpdateScoresButton_Click(object sender, EventArgs e)
{
frmUpdateScore updateScoreForm = new frmUpdateScore(this, CurrentScores.SelectedIndex);
updateScoreForm.Show();
}
}
So turns out the index of my list was -1 when I was trying to call it. I set the SelectedIndex as a local variable then called it. I guess the selected index had to be checked before I could execute it. This the code I fixed.
private void students_SelectedIndexChanged_1(object sender, EventArgs e) {
_selectedIndex = students.SelectedIndex;
if (_selectedIndex > -1)
{
Student student = GetStudent(_selectedIndex); //select index from list
Student students = GetStudent(_selectedIndex); //select index from list
ScoreTotalTextBox.Text = student.GetScoreTotal().ToString(); //show Score Total to box
ScoreCountTextBox.Text = student.GetScoreCount().ToString(); //show Score Count to box
ScoreAverageTextBox.Text = student.GetScoreAverage().ToString(); //show Score Average to box
}
}

How can I pair objects to radio buttons?

I'm working on a small form app, and I have "paired" my radio buttons with lists in a common class. The purpose of this was to turn on/off the corresponding list
public class myType
{
public RadioButton button { get; set; }
public ListBox list { get; set; }
}
I proceed to create these pairs through a for loop inside an array
for (int i = 0; i < broj_botuna; i++)
{
theArray[i] = new myType();
}
I use a common event handler for all the radio buttons:
private void test_CheckedChanged(object sender, EventArgs e)
{
var xx = sender as RadioButton;
//do stuff
positionInArray = Array.IndexOf(theArray, xx);
}
except that the last line of code "xx" should be of type "myType" and not "radioButton" that I managed to retrieve.
So could anyone tell me how do I get the reference from "radioButton" to "myType"? Or is there a better alternative?
You can use Array.FindIndex like:
var positionInArray = Array.FindIndex(theArray, b => b.button == xx);
You could create some constructs that allow you to easily associate your properties to the parent object if you wanted to.
This approach would allow you to always reference your parent type provided that you added a bit more code in your get's and set's.
static void Main()
{
myType item = new myType();
var button = new Button();
myType.button = button;
var list = new ListBox();
myType.list = list;
item = list.GetParent();
bool isSameButton = button == item.button;
bool isSameList = list == item.list;
Assert.IsTrue(isSameButton);
Assert.IsTrue(isSameList);
}
public class myType
{
private RadioButton _button;
public RadioButton button
{
get { return _button; }
set {
value.AssociateParent(this);
_button = value;
}
}
private ListBox _list;
public ListBox list
{
get { return _list; }
set {
value.AssociateParent(this);
_list= value;
}
}
}
public static class Extensions
{
private static Dictionary<object, object> Items { get; set; }
static Extensions()
{
Items = new Dictionary<object, object>();
}
public static void AssociateParent(this object child, object parent)
{
Items[child] = parent;
}
public static object GetParent(this object child)
{
if (Items.ContainsKey(child)) return Items[child];
return null;
}
}

How to create user control for displaying collection of other user controls in WinForms?

I need to create a user control MyTypeListControl to display collection of objects of type MyType using a user controls MyTypeDisplayControl instance for each of those objects.
So that I could
add instance of MyTypeListControl to my WinForm, then
load collection of MyType and
assign it to MyTypeListControl's DataSource.
In the result it should generate and show appropriate count of MyTypeDisplayControl instances in MyTypeListControl's instance.
In case if I needed to show list of properties - equivalent would be DataGrid with specific fields from MyType assigned to specific DataGrid's columns, but I want to view each MyType item as a user control - with more power for visual representation and functionality than DataGrid provides for it's rows.
Is that even possible?
I found this SO resource how to create My collection type, but this is only small part of the problem solution...
It is quite easy (if you know how) and doesn't take so much effort as you might think in the first place (at least for a simple implementation that handles collection of less then 100 items).
So at first lets create a MyType:
public class MyType
{
public static MyType Empty = new MyType(String.Empty, DateTime.MinValue);
public MyType(string myName, DateTime myBirthday)
{
MyName = myName;
MyBirthday = myBirthday;
}
public DateTime MyBirthday { get; private set; }
public string MyName { get; private set; }
}
At next we need a MyTypeControl:
public partial class MyTypeControl : UserControl
{
private MyType _MyType;
private Label labelBirthday;
private Label labelName;
private Label labelSeparator;
public MyTypeControl()
{
InitializeComponent();
}
public event EventHandler MyTypeChanged;
public MyType MyType
{
get { return _MyType; }
set
{
if (_MyType == value)
return;
_MyType = value ?? MyType.Empty;
OnMyTypeChanged(EventArgs.Empty);
}
}
protected virtual void OnMyTypeChanged(EventArgs eventArgs)
{
UpdateVisualization();
RaiseEvent(MyTypeChanged, eventArgs);
}
protected void UpdateVisualization()
{
SuspendLayout();
labelName.Text = _MyType.MyName;
labelBirthday.Text = _MyType.MyBirthday.ToString("F");
labelBirthday.Visible = _MyType.MyBirthday != DateTime.MinValue;
ResumeLayout();
}
private void InitializeComponent()
{
labelName = new Label();
labelBirthday = new Label();
labelSeparator = new Label();
SuspendLayout();
labelName.Dock = DockStyle.Top;
labelName.Location = new Point(0, 0);
labelName.TextAlign = ContentAlignment.MiddleCenter;
labelBirthday.Dock = DockStyle.Top;
labelBirthday.TextAlign = ContentAlignment.MiddleCenter;
labelSeparator.BorderStyle = BorderStyle.Fixed3D;
labelSeparator.Dock = DockStyle.Top;
labelSeparator.Size = new Size(150, 2);
Controls.Add(labelSeparator);
Controls.Add(labelBirthday);
Controls.Add(labelName);
MinimumSize = new Size(0, 48);
Name = "MyTypeControl";
Size = new Size(150, 48);
ResumeLayout(false);
}
private void RaiseEvent(EventHandler eventHandler, EventArgs eventArgs)
{
var temp = eventHandler;
if (temp != null)
temp(this, eventArgs);
}
}
Then comes our magically list control:
public class MyTypeListControl : UserControl
{
private ObservableCollection<MyType> _Items;
public MyTypeListControl()
{
AutoScroll = true;
_Items = new ObservableCollection<MyType>();
_Items.CollectionChanged += OnItemsCollectionChanged;
}
public Collection<MyType> Items
{
get { return _Items; }
}
private void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
UpdateVisualization();
}
private void UpdateVisualization()
{
SuspendLayout();
Controls.Clear();
foreach (var item in _Items)
{
var control = new MyTypeControl { MyType = item, Dock = DockStyle.Top };
Controls.Add(control);
Controls.SetChildIndex(control, 0);
}
ResumeLayout();
}
}
And now simply create the list control in your form or parent control and fill it with some meaningful values:
myTypeListControl.Items.Add(new MyType("Adam", DateTime.UtcNow.Add(-TimeSpan.FromDays(365 * 40))));
myTypeListControl.Items.Add(new MyType("Eva", DateTime.UtcNow.Add(-TimeSpan.FromDays(365 * 38))));

When trying to add a value it just gives the new value C#

I am making a banking ap that keeps track off the amount of money someone has in the bank (called Saldo)
So i created a constuctor that assigns a name to a account and this keeps track of everys person balance
however in my current code i can only add money once and when i change the input it automatically changes to that and doesnt add or subtract (what it is suposed to do)
the important parts of the code are
private void StortL_Click(object sender, EventArgs e)
{
Bankrekening BankrekeningL = new Bankrekening(bankrekeningLinks.Naam, 0);
double saldodouble = 0;
int bedrag = 0;
int decimalL = 0;
int wholeL = 0;
decimalL = Convert.ToInt32(tbDecimaleL.Text);
wholeL = Convert.ToInt32(tbWholeL.Text) * 100;
bedrag = wholeL + decimalL;
Bankrekening BankrekeningL2 = new Bankrekening(bankrekeningLinks.Naam, BankrekeningL.Saldo);
BankrekeningL2.Stort(bedrag);
lbIsaldoL.Text = Convert.ToString(BankrekeningL2.Saldo);
}
}
}
And
class Bankrekening
{
//datavelden
private int rekeningnummer;
private string naam;
private int saldo;
private static int volgendeVrijeRekeningnummer = 2001;
//properties
public int Rekeningnummer { get { return rekeningnummer; } }
public string Naam { get { return naam; } }
public int Saldo { get { return saldo; } }
//constructors
public Bankrekening(string naam)
{
this.naam = naam;
saldo = 0;
//volgendeVrijeRekeningnummer is klassevariable,
//je kunt this niet gebruiken
rekeningnummer = volgendeVrijeRekeningnummer++;
}
public Bankrekening(string naam, int saldo)
{
this.naam = naam;
this.saldo = saldo;
}
public void NeemOp(int bedrag)
{
saldo = saldo+bedrag;
}
public void Stort(int bedrag)
{
saldo = saldo + bedrag;
}
public void MaakOverNaar(Bankrekening andereRekening, int bedrag)
{
//zelf invullen
}
}
So what currently is happening is that instead of adding the number in a text box to the value of saldo (the previous inputs of the text box) it just sets the value of saldo to the value of whatever is in the text box.
E.G. i want to add 50 to my bankacount to which i previously added 100 euros so my label that keeps track of the balance should give 150 but instead it gives me 50.
you are everytime creating a new object, rather than using the same object for a same person .
So if you have already created an object for persons AAA
and he is adding money , you need to use the same object created rather than creating it again .
this line i think is the problem :
Bankrekening BankrekeningL = new Bankrekening(bankrekeningLinks.Naam, 0);
Possible solution :
You might keep a list of your Bankrekening objects , and using LINQ check if for a person the object is already present .
If it is present then use the same object , else create a new object.
Something like
List<Bankrekening> list = new List<Bankrekening>();
if(list.Any(x=>x.Name == "XYZ")>
// your code to add
else
Bankrekening BankrekeningL2 = new Bankrekening(bankrekeningLinks.Naam, BankrekeningL.Saldo);
You need to move the declaration of BankrekeningL outside of the function into the form to preserve its value, currently you are creating a new instance every button click
Bankrekening BankrekeningL;
public FormName()
{
BankrekeningL = new Bankrekening("name");
}
private void StortL_Click(object sender, EventArgs e)
{
double saldodouble = 0;
int decimalL = Convert.ToInt32(tbDecimaleL.Text);
int wholeL = Convert.ToInt32(tbWholeL.Text) * 100;
int bedrag = wholeL + decimalL;
BankrekeningL.Stort(bedrag);
lbIsaldoL.Text = BankrekeningL.Saldo.ToString();
}

ListBox and object properties

Been looking for a clear example of this.
I made a new object including setting several properties, added the whole object to the listBox then wrote a string to describe them. Now I want one item from the lsitBox object at the selected index. There are many syntaxes that appear to have similar but different usages it is complicating the search...
Pseudocode:
SpecialClass object = new SpecialClass;
object.propertyA;
Object.PropertyB;
listBox.Items.Add(object);
//listBox.SelectedItem[get propertyA]? What would retrieve propertyA or propertyB from the //list after putting the object in the list?
.... I tried to use this variable setting, something like this...
MRecipeForm parent = new MRecipeForm();
ListViewItem item = new ListViewItem();
item.Tag = parent.recipeListB.Items;
var myObject = (double)parent.recipeListB.SelectedItems[0].Tag;
// here you can access your properties myObject.propertA etc...
....
This is my current code that throws an exception:
MRecipeForm parent = new MRecipeForm();
ListViewItem item = new ListViewItem();
item.Tag = parent.recipeListB.Items;
Substrate o = ((ListBox)sender).SelectedItem as Substrate;
double dryWtLbs = o.BatchDryWtLbs; //BatchDryWtLbs is type double
Just store your object into your item's Tag property. When you adding your item:
ListViewItem item = new ListViewItem();
item.Tag = myObject;
...
Then:
var myObject = (SpecialClass)listBox.SelectedItems[0].Tag;
// here you can access your properties myObject.propertA etc...
Example to retrieve a double after changing selected index :
Forms 1 has a label : label1 and a listbox : listBox1
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
var object1 = new SpecialClass { Text = "First line", Number = 1d };
var object2 = new SpecialClass { Text = "Second line", Number = 2d };
listBox1.Items.Add(object1);
listBox1.Items.Add(object2);
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
SpecialClass o = ((ListBox)sender).SelectedItem as SpecialClass;
label1.Text = o.Number.ToString();
}
}
public class SpecialClass
{
public string Text { get; set; }
public double Number { get; set; }
public override string ToString()
{
return Text;
}
}

Categories