I am using a ListBox that stores items such as camping gear. The ListBox will have tent, camping chairs, coffee and so on.
Then I created a list that has the prices for each item called lstprices.
When I double click on the entry it will appear in another ListBox while pulling the price from the lstprices and add it to a subtotal Label.
try
{
if (lstItems.Items.Count > 0)
{
lstOrder.Items.Add(lstItems.SelectedItem.ToString());
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
I am assuming I would somehow add information to the lstOrder.Items since I know the element numbers but don't understand how to display it in my Label.
I hope this makes sense.
Also for this statement:
decimal STotal = decimal.Parse(lblSubtotal.Text.ToString());
it errors stating that its in the wrong format when I double click the item.
Sorry i cannot comment so have to post an answer:
if you have to keep track of multiple properties of an object then you should create a class of it for example (Object Oriented Programming):
public class Product
{
public string Name {get;set;}
public double Price {get;set;}
public Product(string name, double price)
{
Name = name;
Price = price
}
}
this way you can just do: Product chair = new Product("Camping Chair", 12.99);
or you can fill a list
List<Product> products = new List<Product>()
{
new Product("Camping Chair", 12.99),
new Product("Tent", 25.99)
}
and then display your products in a list or datagridview etc. it will be a better approach then maintaining two lists with names and prices.
this will also make work with the listbox easier it has a property called SelectedItem which you can cast to your class and then reference it properties for example:
Product selectedProduct = myListbox.SelectedItem as Product;
myLabel.Text = selectedProduct?.Price.ToString();
EDIT:
since classes have not been covered by, what you can do is use a Dictionary<string,double> to keep track of your prices and keys (product name) or at least a List<KeyValuePair<string,double>> :
Below a quick example to get you started:
Dictionary<string, double> products = new Dictionary<string, double>()
{
{"Camping Chair",33.0},
{"Stool",12.99},
};
//accessing the price via the key, which
var price = products.Where(x => x.Key == "Stool").SingleOrDefault();
// you could then pass in the selected item of your list box as string
var price = products.Where(x => x.Key == listbox.SelectedItem.ToString()).SingleOrDefault();
More about dictionary at msdn
More about KeyValuePair at msdn
Related
This may be a shot in the dark, but I seem to have this strange bug in my code. I have a system that stores a bunch of vehicle objects (class is called Vehicle) in a VehicleList stored in a Business class. Each of these vehicles has a list attribute called activities, which stores different types of Activities. Currently I have a system that adds the vehicles to a datagridview where I can select a record and it opens up a form with a list of the vehicles activities where I can add and remove them etc. This works fine with adding the activities to the list in the current selected vehicle. The problem I am having, which could be an underlying issue, is that when I open the vehicle list form and select a vehicle to view its activity list, it removes all records from the list. I have done some debugging and found that the activities are stored in the list of that vehicle right up until I click a row in the datagridview.
The hierarchy looks like this:
<Business> //Contains VehicleList
<VehicleList> //Contains Vehicles
<Vehicle> //Contains ActivityList
<ActivityList> //Contains Activities
Here is the method I use to select a row:
private void DataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex != -1)
{
string registration = dataGridViewRegisteredVehicles.Rows[e.RowIndex].Cells[0].Value.ToString();
foreach (Vehicle vehicle in Business.VehicleList)
{
if (vehicle.Registration == registration)
{
_selectedVehicle = vehicle;
}
}
}
else
{
MessageBox.Show("This is not a record", "", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
}
Where _selectedVehicle =
private Vehicle _selectedVehicle;
public Vehicle SelectedVehicle
{
get { return _selectedVehicle; }
set
{
_selectedVehicle = value;
}
}
Here is the list in the Vehicle class:
private List<Activity> _activityList = new List<Activity>();
public List<Activity> ActivityList
{
get => _activityList;
}
I cant wrap my head around why the list is cleared when I click a record. I checked the list before I clicked a record in the datagridview and it showed a correct count for the amount of activities in the list, but when I check the list afterwards, the list count is zero. Has anyone seen this before?
Method for adding vehicles to the vehicle list:
Vehicle vehicle = new Vehicle
{
Registration = registration,
Model = model,
Make = make,
Year = int.Parse(year),
Cost = int.Parse(cost)
};
Business.VehicleList.Add(vehicle);
Method for adding from list to datagridview:
for (int i = 0; i < Business.VehicleList.Count; i++)
{
dataGridViewRegisteredVehicles.Rows.Add(
Business.VehicleList[i].Registration,
Business.VehicleList[i].Model,
Business.VehicleList[i].Make,
Business.VehicleList[i].Year,
Business.VehicleList[i].Cost
);
}
I tried setting the datagridview datasource to the list, but this just adds empty cells to the datagridview
I want to create an application where the user can enter items and the price, then show the most expensive and the cheapest item.
I'm totally new to C# and have no programming experience of any language, started to learn 2,5 weeks ago. I don't understand how I can link the item with the price and then do the calculation. The penny hasn't dropped yet in terms of how I can build an application :(
ItemInput();
PricingInput();
}
private static void ItemInput()
{
Console.WriteLine("Add your items and price, once you're done, type 'end' ");
AskForTheItem();
AskForThePrice();
}
static void AskForTheItem()
{
while (itemPrice != "end")
{
Console.Write("Add your item:");
string item = Console.ReadLine();
Console.Write("Add the price:");
int price = int.Parse(Console.ReadLine());
itemPrice = Console.ReadLine();
}
Console.WriteLine("Add your item: ");
name = Console.ReadLine();
numberOfItems++;
}
static void AskForThePrice()
{
Console.WriteLine("Add the price: ");
price = int.Parse(Console.ReadLine());
numberOfPrice++;
}
private static void PricingInput()
{
Console.WriteLine($"The cheapest item is: {name} and the most expensive item is: {name} ");
private static void ItemInput()
{
PricingInput(AskForTheItem());
}
static Dictionary<String, int> AskForTheItem()
{
var result = new Dictionary<String, int>();
Console.WriteLine("Add your items and price, once you're done, type empty item ");
while (1)
{
Console.Write("Add your item or keep empty :");
string item = Console.ReadLine();
if(String.IsNullOrEmpty(item)) return result;
Console.Write("Add the price:");
while(!int.TryParse(out var price, Console.ReadLine()) Console.Write("Wrong price, please Add the price:");
result.Add(item, price);
}
}
private static void PricingInput(Dictionary<String,int> list)
{
String minItem = null;
int minPrice = -1;
String maxItem = null;
int maxPrice = -1;
foreach(var i in list) {
if(price<0 || i.Value<price) { minItem = i.Key; minPrice=i.Value;}
if( i.Value>price) { maxItem = i.Key; maxPrice=i.Value;}
Console.WriteLine($"The cheapest item is: {1} and the most expensive item is: {2} ",minItem,maxItem); }
Welcome to StackOverflow! Your question seems to be pretty broad but I think what you'd need is some first steps into object-oriented programming with classes.
Your code seems like a good start but for storing the information you'll need some objects.
You can create your own objects using a class. In this case you class would need a property for its name and one for it's price.
Defining the class would be as follows (you should do that in a new file):
class MyItem{
public string Name { get; set; }
public int Price { get; set; }
}
Then at the start of the class with the AskForTheItems method and probably also the Main method, you need to add a List to store the items. You'd do that like this:
private static List<MyItem> items = new List<MyItem>();
For the method which gets the items, you'll need to some adjustments. You also don't need the numberOfItems-variable anymore since you can just call items.Count if you need it.
private static void AskForTheItems()
{
do
{
Console.WriteLine("Add your item:");
// get the name
Console.Write("Name: ");
string name = Console.ReadLine();
// get and convert the price
Console.Write("Price: ");
int price = int.Parse(Console.ReadLine());
// create the item and fill it with the values
MyItem item = new MyItem();
item.Name = name;
item.Price = price;
// add the item to your list
items.Add(item);
// ask if the user want's to add another one
Console.WriteLine("Again? (y/n)");
}
while (Console.ReadKey(true).Key != ConsoleKey.N);
}
Printing the cheapest and most expensive one is fairly easy using Linq (there might even be an easier/better way).
private static void PrintCheapestAndMostExpensive() {
// get the first item where the price is the same as the minimum of all prices in the list
MyItem cheapestItem = items.First(i => i.Price == items.Min(i2 => i2.Price));
// get the first item where the price is the same as the maximum of all prices in the list
MyItem mostExpensiveItem = items.First(i => i.Price == items.Max(i2 => i2.Price));
Console.WriteLine($"The cheapest item is: {cheapestItem.Name} and the most expensive item is: {mostExpensiveItem.Name}");
}
I hope this helps. If you have any questions, feel free to ask - I'll try to explain anything you don't understand yet.
By the way there a are few things I didn't do/cover because I feel like it'd be a bit too much to explain for a small program like this. Currently there is no error handling when converting the input-string to an int (bad). There are also easier ways to write the initialisation for the item but I figured this way it's easier to understand.
Also with this code it always prints the first item which has the lowest price. If there are two which both have the lowest price, this might be a problem.
Linq itself is fairly hard (but very very important), that's why I would strongly reccomend you to read something about it. I'd happily explain the Linq I used here with more detail but since it's such a huge topic, I won't cover much more.
Is it possible to sum up all of the item's price inside a ListBox? I have this ListBox that displays items from a DataGridView, and each of their prices are in priceTextBox Please refer from the picture below.
What I want to do is to display the sum of all the item's price and display it at the totalTextBox.
I have already done this code but I think this won't work.
private void menuListBox_SelectedValueChanged(object sender, EventArgs e)
{
int x = 0;
string Str;
foreach (DataGridViewRow row in menuDataGrid.Rows) //this part displays the price of each item to a textbox so this is good.
{
if (row.Cells[3].Value.ToString().Equals(menuListBox.SelectedItem.ToString()))
{
pricetxtbox.Text = row.Cells[5].Value.ToString();
break;
}
}
foreach (string Str in row.Cells[5].Value.ToString().Equals(menuListBox.SelectedItem.ToString())) //now this is the part where I want to happen the adding the prices of all items in the listbox. this also gives me an error at row saying it doesn't exist in the context
{
x = x + Convert.ToInt32(Str);
totaltxtbox.Text = x;
}
}
Will appreciate any help! Thanks!
Try this out...
Func<string, DataGridViewRow> getRow = (menuCode) =>
{
return menuDataGrid.Rows.Cast<DataGridViewRow>()
.First(r => ((string)r.Cells[3].Value).Equals(menuCode));
};
var selected = menuListBox.SelectedItem.ToString();
pricetxtbox.Text = getRow(selected).Cells[5].Value.ToString();
totaltxtbox.Text = menuListBox.Items.Cast<object>()
.Select(o => o.ToString())
.Select(i => (int)getRow(i).Cells[5].Value)
.Sum()
.ToString();
I think you should change your approach, by separating completely data and display.
To do that, you could create a class which will contain data for each row of your DataGrid :
public class MyItem
{
public string Caption { get; set; }
public int Price { get; set; }
}
And then in your codebehind, you store a list of these items :
private List<MyItem> AllItems = new List<MyItem>();
Finally, you set this collection as the source of your DataGrid :
menuDataGrid.DataSource = AllItems;
Then, all your data is stored in a collection you own, and to sum prices it's much simpler :
using System.Linq;
private int ComputeSum()
{
return (AllItems.Sum(item => item.Price));
}
The next step is to use Binding and a BindingList, wich allows the DataGrid to refresh automatically when new items are added in "AllItems": see this well explained post.
I have a ListBox (sortedListBox) which I have populated like this by the items in a Combobox (allItemsComboBox):
int index = sortedListBox.FindString(allItemsComboBox.Text, -1);
if (index == -1)
{
var item=new { Text = allItemsComboBox.Text , Value = allItemsComboBox.Value};
sortedListBox.Items.Add(item);
}
The DisplayedMember of sortedListBox is "Text" and ValueMember of it is "Value".
Now I want to iterate through all items in the ListBox and get its values:
public static string ListBoxToString(ListBox lb)
{
List<string> values = new List<string>();
for (int i = 0; i < lb.Items.Count; i++)
{
values.Add(lb.Items[i].ToString());
}
string result = String.Join(",", values);
return result;
}
In this line: values.Add(lb.Items[i].ToString()); I get:
{ Text = "Size" , Value = "cte1.Size"}
I just want to have the value , which is "cte1.Size"
How can I iterate through the items in the ListBox and get the ValueMember of these?
I don't know that there's any way to ask the ListBox to evaluate the ValueMember for you in that way... and because you're using an anonymous type, it becomes harder to get the value.
Options:
Use a named type instead, and cast each item to that
Use dynamic typing
For example:
public static string ListBoxToString(ListBox lb)
{
var values = lb.Items
.Cast<dynamic>()
.Select(x => x.Value.ToString());
return string.Join(",", values);
}
Dynamic typing provides the most immediate fix, but I'd strongly encourage you to consider using a custom type. (It needn't take more than a few lines to write.)
There are two problems with your approach:
1.) The ListBox stores items as a collection of objects which means accessing them with listBox.Items[idx] will only give you back an object and not the actual type. You could get around that with casting it to the appropriate type but it won't work in your case because of the next point.
2.) You create your items as anonymous objects with var item = new { ... }. You can't cast to this kind of type. You could use the dynamic keyword to get around that but I wouldn't do that as you lose type safety.
What you could do is create a simple class for the date you want to store and use that instead of an anonymous type:
class MyData
{
public string Text { get; set; }
public string Value { get; set; }
}
I get this error while trying to add items to the combobox at runtime.Is there a way to add items on runtime , even if my combobox datasource is set .
Example:My combobox has items , but i want to display "Select Category" type of statement when my form loads .
Thanks !!!
Assuming
public class Product
{
public int Id {get;set;}
public string Name {get;set;}
}
with EF
var list = context.Products.Where(x = > x.Active == true).ToList();
list.Insert(0, new Product() { Id = -1, Name = "Please Select" });
selectBox.DataSource = list;
The idea is to get your database list of objects into List < Product > () first, then simply add fake item on top of that list.
If all you want to do is display "Select Category", try this.
DropDownList1.Items.Insert(0, new ListItem("Select Category"));
I'm not sure if it's possible to do this after the DataBind() but I think it should be OK.