thanks in advance for any help!
A bit of background basically I am building an application that stores vehicles (cars,truck,buses), I have a vehicle superclass and all the individual classes (car.cs, truck.cs, minibus.cs) inherit from this super class.
I also have a class called 'fleet' that I would like to add the vehicles to an then display the results in a list box.
I have everything else working but I cannot get the trucks and minibus's to update and display on the list box like the cars do.
Here is my fleet class which includes the car.cs; and it works fine and the data taken from the car form gets added and displayed in the listbox.
class Fleet
{
private List<Vehicle> theFleet = new List<Vehicle>();
public List<Vehicle> fleet
{
get
{
return theFleet;
}
}
public void deleteFromFleet(Vehicle aCar)
{
theFleet.Remove(aCar);
}
public void addToFleet(Vehicle aCar)
{
theFleet.Add(aCar);
}
}
Here is my main form, that has the list box on it:
public partial class FrmHireCo : Form
{
private Fleet myFleet = new Fleet();
private ClientList mycustomer = new ClientList();
//Fleet object used to store cars
public FrmHireCo()
{
//Default constructor
InitializeComponent();
}
private void updateFleetList()
{
lstFleet.Items.Clear();
foreach (Car c in myFleet.fleet)
{
string line = "Car: " + c.make+" " + c.colour;
lstFleet.Items.Add(line);
}
}
private void updateClientList()
{
customers.Items.Clear();
foreach (Customer c in mycustomer.clientlist)
{
string line = "Customer: " + c.name + " " + c.address;
customers.Items.Add(line);
}
}
private void btnAddCar_Click(object sender, EventArgs e)
{
//Add a new car
FrmCar carGui = new FrmCar(); //Form used to add new car
carGui.ShowDialog();
Car myCar = carGui.car; //Get new car from form
myFleet.addToFleet(myCar); //Add to fleet list
updateFleetList(); //Uodate fleet list
}
private void lstFleet_SelectedIndexChanged(object sender, EventArgs e)
{
if (lstFleet.SelectedIndex > -1)
{
int index = lstFleet.SelectedIndex;
Car myCar = myFleet.fleet.ElementAt(index);
FrmCar carGui = new FrmCar();
carGui.car = myCar;
carGui.Show();
}
}
private void btnCustomer_Click(object sender, EventArgs e)
{
FrmCustomer customerGui = new FrmCustomer();
customerGui.ShowDialog();
Customer mycustomer = customerGui.customer;
mycustomer.addToClientList(mycustomer);
updateFleetList();
}
private void customers_SelectedIndexChanged(object sender, EventArgs e)
{
if (customers.SelectedIndex > -1)
{
int index = customers.SelectedIndex;
Customer myCustomer = mycustomer.clientlist.ElementAt(index);
FrmCustomer customerGui = new FrmCustomer();
customerGui.customer = myCustomer;
customerGui.Show();
}
}
}
Cheers for any help!
private void updateFleetList()
{
lstFleet.Items.Clear();
foreach (Vehicle c in myFleet.fleet)
{
string line = "Car: " + c.make+" " + c.colour;
lstFleet.Items.Add(line);
}
}
You should include all vehicles.
private void updateFleetList()
{
lstFleet.Items.Clear();
foreach (Vehicle v in myFleet.fleet)
{
lstFleet.Items.Add(v);
}
}
Also, just override ToString in all your Vehicle subclasses and the ListBox will use that inherently; this way not every Vehicle needs a Make or Color property.
Related
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
}
}
I have a Class where there a 2 variables int ID and string name. I made a list of several objects and loaded them onto a listbox. The listbox only show the name. Is there a way to retrieve the ID from the listbox?
class Show
{
private int _Id;
private string _Naam;
private string _Genre;
public override string ToString()
{
return Naam;
}
}
from a database i make a list of objects.
private void bttn_zoek_Click(object sender, EventArgs e)
{
foreach (object a in List<show> List)
{
listbox1.Items.Add(a);
}
}
I hope this is enough
Assuming WinForms, here is a super simple example of overriding ToString() to control how the class is displayed in the ListBox, and also how to cast the selected item in the ListBox back to your class type so you can extract values from it. There are other ways to accomplish this task, but you should understand a bare bones example like this first:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
SomeClassName sc1 = new SomeClassName();
sc1.ID = 411;
sc1.Name = "Information";
listBox1.Items.Add(sc1);
SomeClassName sc2 = new SomeClassName();
sc2.ID = 911;
sc2.Name = "Emergency";
listBox1.Items.Add(sc2);
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (listBox1.SelectedIndex != -1)
{
SomeClassName sc = (SomeClassName)listBox1.Items[listBox1.SelectedIndex];
label1.Text = "ID: " + sc.ID.ToString();
label2.Text = "Name: " + sc.Name;
}
}
}
public class SomeClassName
{
public int ID;
public string Name;
public override string ToString()
{
return ID.ToString() + ": " + Name;
}
}
Posting some of your code would be nice. Have you tried listBox.items[index].ID?
Here I'm assuming that index is whatever index you're currently searching for.
You can also try listBox.SelectedItem[index].ID if you're doing something like an event.
I'm making a Pacman windows store app game. I use win2d library to make animations. I have a problem in navigation between pages.
Here's my main page, it creates new Game.
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
//Game gm = new Game();
}
private void playButton_Click(object sender, RoutedEventArgs e)
{
Game gm = new Game();
}
private void exitButton_Click(object sender, RoutedEventArgs e)
{
Application.Current.Exit();
}
private void resultsButton_Click(object sender, RoutedEventArgs e)
{
}
}
but in Game class when end finishes I have to somehow comeback to my main page. I have tried many ways but they doesn't work for me.
Game class:
public Game()
{
this.InitializeComponent();
Window.Current.Content = this;
}
private void canvas_CreateResources(CanvasAnimatedControl sender, Microsoft.Graphics.Canvas.UI.CanvasCreateResourcesEventArgs args)
{
args.TrackAsyncAction(CreateResourcesAsync(sender).AsAsyncAction());
}
async Task CreateResourcesAsync(CanvasAnimatedControl sender)
{
ghostImages = new List<CanvasBitmap>();
ghostImages.Add(await CanvasBitmap.LoadAsync(sender.Device, new Uri("ms-appx:///Assets/ghost1.png")));
ghostImages.Add(await CanvasBitmap.LoadAsync(sender.Device, new Uri("ms-appx:///Assets/ghost2.png")));
ghostImages.Add(await CanvasBitmap.LoadAsync(sender.Device, new Uri("ms-appx:///Assets/ghost3.png")));
ghostImages.Add(await CanvasBitmap.LoadAsync(sender.Device, new Uri("ms-appx:///Assets/ghost4.png")));
ghostImages.Add(await CanvasBitmap.LoadAsync(sender.Device, new Uri("ms-appx:///Assets/Pacman_25.png")));
StartNewGame();
}
private void Canvas_Draw(ICanvasAnimatedControl sender, CanvasAnimatedDrawEventArgs args)
{
Map.drawBorders(args);
using (var session = args.DrawingSession)
{
session.DrawImage(hero.getImage1(), hero.getX(), hero.getY());
for (int i = 0; i < ghostList.ToArray().Length; i++)
{
session.DrawImage(ghostList[i].getImage(), ghostList[i].getX(), ghostList[i].getY());
}
int bestScore = 1, score = 3;
session.DrawText("Rekordas: " + bestScore, Constants.WIDTH / 3 * 1.8f, Constants.HEIGHT + Constants.SHOWINFOSIZE / 2, Windows.UI.Colors.White);
session.DrawText("Rezultatas: " + score, Constants.BLOCKSIZE, Constants.HEIGHT + Constants.SHOWINFOSIZE / 2, Windows.UI.Colors.White);
session.DrawText("Gyvybės: ", Constants.BLOCKSIZE, Constants.HEIGHT + Constants.SHOWINFOSIZE / 1, Windows.UI.Colors.White);
for (int i = 0; i < 3; i++)
session.DrawImage(hero.getImage1(), Constants.BLOCKSIZE + 150 + (Constants.BLOCKSIZE + 5) * i, (int)Constants.HEIGHT + Constants.SHOWINFOSIZE / 1 - Constants.BLOCKSIZE + 5);
}
}
public void GameOver()
{
playing = false;
//Frame.Navigate(typeof(MainPage));
//Dispose();
//this.Dispose();
//var page = new MainPage();
//Window.Current.Content = page;
//MainPage mn = new MainPage();
//if (name == null)
//{
// name = "Student";
//}
//Window.Current.Content = new MainPage();
//mn.UpdateLayout();
}
How can I navigate through pages? Thanks.
Here are some methods that you might find helpful (from a class that I use to wrap navigation logic inside)
//Better made the class a singleton but I've skipped that part to for brifety
public class Navigation
{
public bool CanGoBack
{
get
{
var frame = ((Frame)Window.Current.Content);
return frame.CanGoBack;
}
}
public Type CurrentPageType
{
get
{
var frame = ((Frame)Window.Current.Content);
return frame.CurrentSourcePageType;
}
}
public virtual void GoBack()
{
var frame = ((Frame)Window.Current.Content);
if (frame.CanGoBack)
{
frame.GoBack();
}
}
public virtual void NavigateTo(Type sourcePageType)
{
((Frame)Window.Current.Content).Navigate(sourcePageType);
}
public virtual void NavigateTo(Type sourcePageType, object parameter)
{
((Frame)Window.Current.Content).Navigate(sourcePageType, parameter);
}
public virtual void GoForward()
{
var frame = ((Frame)Window.Current.Content);
if (frame.CanGoForward)
{
frame.GoForward();
}
}
}
You use it like this (if we assume the aforementioned methods reside in a class named Navigation that you have instance of):
//To go to Game page
Navigation.NavigateTo(typeof(Game));
//To go to Main page and pass some arguments
Navigation.NavigateTo(typeof(MainPage), winnerId);
//To go back
Navigation.GoBack();
Addition
You could receive your passed parameters in your views like this:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var receivedParameter = e.Parameter as TheTypeOfThePassedParameter;
}
Additional option to pass data is to create one static or singleton application-wise class (visible from everywhere) containing some values that you want available throughout your app
I suggest you to consider Model View View Model pattern to manage your App's navigation logic and contents. (Channel9 introductive video)
To help you with navigation, you could use MVVM Light library that exposes some useful navigation methods:
In ViewModelLocator.cs you could define a string for every page to be navigated:
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
var nav = new NavigationService();
nav.Configure("MainMenu", typeof(MainMenuView));
nav.Configure("About", typeof(AboutView));
nav.Configure("Game", typeof(GameView));
SimpleIoc.Default.Register<INavigationService>(() => nav);
SimpleIoc.Default.Register<MainMenuViewModel>();
SimpleIoc.Default.Register<AboutViewModel>();
SimpleIoc.Default.Register<GameViewModel>();
}
A typical ViewModel could be:
public class GameViewModel : ViewModelBase
{
private INavigationService _navigationService;
public GameViewModel(INavigationService NavigationService)
{
_navigationService = NavigationService;
}
// Then, when you want to expose a navigation command:
private RelayCommand _navigateToMenuCommand;
public RelayCommand NavigateToMenuCommand
{
get
{
return _navigateToMenuCommand
?? (_navigateToMenuCommand = new RelayCommand(
() =>
{
_navigationService.NavigateTo("MainMenu");
}
{
}
}
And .XAML:
<Button Content="Back to Main Menu" Command={Binding GameViewModel} />
I have 3 forms in my application : frmTrucks, frmEditTruck and frmEditContent.
frmTrucks shows my Trucks in a grid.
I add a truck, or choose one of the trucks from the grid to edit in frmEditTruck
public void Edit()
{
using (NestedUnitOfWork nuow = session.BeginNestedUnitOfWork())
{
Truck currentTruck = nuow.GetNestedObject(
xpcTruck[gvTruck.GetDataSourceRowIndex(gvTruck.FocusedRowHandle)])
as Truck;
using (frmEditTruck form = new frmEditTruck(currentTruck))
{
if (form.ShowDialog() == DialogResult.OK)
nuow.CommitChanges();
}
}
}
in frmEditTruck there are some text boxes for truck properties and two buttons.
btnSave and btnAddContent. btnSave saves the changes (now.CommitChanges();). btnAddContent's click code is :
Truck truck;
Session session;
public frmEditTruck(Truck truck)
{
InitializeComponent();
this.truck = truck;
this.session = truck.Session;
}
private void btnAddContent_Click(object sender, EventArgs e)
{
TContent content = new TContent(session);
using (frmEditTContent form = new frmEditTContent(content, truck))
{
if (form.ShowDialog() == DialogResult.OK)
truck.TContents.Add(content);
}
}
it shows frmEditContent. I can Add content to my truck. the problem is when I press AddContent and then cancel it. After that when I press the save button on my frmEditTruck it would add an empty row to my Content Table. I want to fix this problem. how can I fix it? I'm not sure my problem is clear enough for you. Please let me know
public class Truck : XPObject
{
.
.
.
[Association("Truck-TContents")]
public XPCollection<TContent> TContents { get { return GetCollection<TContent>("TContents"); } }
}
public class TContent : XPObject
{
.
.
.
private Truck truck;
[Association("Truck-TContents")]
public Truck Truck
{
get
{
return truck;
}
set
{
SetPropertyValue("Truck", ref truck, value);
}
}
}
private void btnAddContent_Click(object sender, EventArgs e)
{
TContent content = new TContent(session);
using (frmEditTContent form = new frmEditTContent(content, truck))
{
if (form.ShowDialog() == DialogResult.OK)
truck.TContents.Add(content);
}
}
I've changed the code to:
private void btnAddContent_Add(object sender, EventArgs e)
{
TContent content = new TContent(session);
using (frmEditTContent form = new frmEditTContent(content, truck))
{
if (form.ShowDialog() == DialogResult.OK)
{
truck.TContents.Add(content);
}
else
{
if (session.TrackingChanges)
session.RollbackTransaction();
}
}
}
and it works properly.
Ok guy,
i have made a simple program that has a web form where you fill in details fruit name, kg and cal count. i have then used session variables to get the fruit name from the form on default page and display them on about page in a drop down menu. that's all working fine, what i cant seem to work out is on the about page how to get it so the user selects a item from the drop down (created from form on default page) then enter a int how many they want (in text box) and have there selection and amount output on a list box on about page. il post the code i have so far any help would be much appreciated.
default page
public class Fruit
{
private string fName;
private int grams, calsPerGram;
private bool edible;
public Fruit(string n, int g, int c, bool e)
{
grams = g;
calsPerGram = c;
edible = e;
fName = n;
}
public int totalCalories()
{
return grams * calsPerGram;
}
public string getFruitInfo()
{
string s;
if (edible == true)
{
s = fName + " is yummy and it has " + totalCalories() +
"calories";
}
else
{
s = "Hands off! Not edible";
}
return s;
}
}
public partial class _Default : System.Web.UI.Page
{
List<Fruit> myBasket;
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
myBasket = new List<Fruit>();
Session["listSession"] = myBasket;// seassion start
}
}
protected void Button1_Click1(object sender, EventArgs e)
{
// Session["Fruitname"] = TbxName.Text; // my session i have made
MyFruit = Session["Fruitname"] as List<string>;
//Create new, if null
if (MyFruit == null)
MyFruit = new List<string>();
MyFruit.Add(TbxName.Text);
Session["Fruitname"] = MyFruit;
abc.Items.Clear();
Fruit f = new Fruit(TbxName.Text, int.Parse(TbxWeight.Text),
int.Parse(TbxCal.Text), CheckBox1.Checked);
myBasket = (List<Fruit>)Session["listSession"]; // session used
myBasket.Add(f);
foreach (var item in myBasket)
{
abc.Items.Add(item.getFruitInfo()); // List box used
}
}
public List<string> MyFruit { get; set; }
}
About page
public partial class About : Page
{
protected void Page_Load(object sender, EventArgs e)
{
MyFruit = Session["Fruitname"] as List<string>;
//Create new, if null
if (MyFruit == null)
MyFruit = new List<string>();
DropDownList1.DataSource = MyFruit;
DropDownList1.DataBind();
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
Drinklabel.Text = "Your Chosen Beverage is A " + DropDownList1.SelectedValue.ToString() + " Drink.";
}
public List<string> MyFruit { get; set; }
}
You do not necessarily need a separate class for calculating cost, but I recommend that you use a Label to display the selected fruit, amount desired and total price, like this in your About page:
Create a Button with Calculate text that has a click event handler, a calculatePrice method, a TextBox for quantity and a Label for display, like this:
protected void ButtonCalculate_Click(sender object, EventArgs e)
{
decimal total = calculatePrice(DropDownList1.SelectedItem.Text,
TextBoxQuantity.Text.Trim());
LabelResult.Text = "You would like " + TextBoxQuantity.Text.Trim() +
DropDownList1.SelectedItem.Text + "(s) for a total of $" +
total.ToString();
}
private decimal calculatePrice(string fruitName, int quantity)
{
// Ask the database for the price of this particular piece of fruit by name
decimal costEach = GoToDatabaseAndGetPriceOfFruitByName(fruitName);
return costEach * quantity;
}