Writing in List using switch c# - c#

I wanted to insert data from textbox to list.
But whenever I am trying to gather to count the number of rows no rows are created. or no data are stored in the list
Here is the sample of the code.
foreach (classfile row in list)
{
switch (row.fld_ID)
{
#region Q1
case 1:
row.fld_Answer = QuestionTextBox1.Text.ToUpper().Trim();
break;
#endregion
#region Q2
case 2:
row.fld_Answer = QuestionTextBox2.Text.ToUpper().Trim();
}
}

Related

Display item value to specific datagridcolumn selected from datagridcomboboxcolumn and dynamically compute for the total for each selection

I am developing windows form using c# and using datagridview object. I am almost done but I have a problem with displaying item value to a specific column(PTS GAIN COLUMN) that I selected in a comboboxcell all inside datagridview. Data is selected from database(coded). The column(PTS GAIN COLUMN) where I want to display the selected item value has no entry in the database. It is empty. I want that every time I select a item from a comboboxcell per row is that it will display the value to a specific column(PTS GAIN COLUMN) and compute the total dynamically/real-time(I want to show the result in label.text)
Also the combobox cell has items YES,NO,NA(this has no datatable, I just added the items by coding combobox.items.add("yes/no/na"). Yes item will get value depending on the column PTS AVAIL and display on column PTS GAIN. If I select no, 0 will display in PTS GAIN column, and if NA, both PTS AVAIL and PTS GAIN will have 0. Again I want to if possible to compute the total real-time.
Any help with this matter is much appreciated. I am meeting a dead line so please, anyone! Have a great day! Btw, I will post screenshot of the program, and if you want to see a particular block of code for reference just comment.
You will need to hook up with 2 events to accomplish this but for the most part it is pretty easy.
private void MyInitializeComponent()
{
dg.CurrentCellDirtyStateChanged += Dg_CurrentCellDirtyStateChanged;
dg.CellValueChanged += Dg_CellValueChanged;
this.CalculateTotals();
}
private void Dg_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (dg.Columns[e.ColumnIndex].Name == "Choices")
{
switch (dg.Rows[e.RowIndex].Cells["Choices"].Value.ToString())
{
case ("Yes"):
{
dg.Rows[e.RowIndex].Cells["PointsGained"].Value =
dg.Rows[dg.CurrentCell.RowIndex].Cells["PointsAvailable"].Value;
break;
}
case ("No"):
{
dg.Rows[e.RowIndex].Cells["PointsGained"].Value = 0;
break;
}
case ("NA"):
{
dg.Rows[e.RowIndex].Cells["PointsGained"].Value = "NA";
break;
}
}
this.CalculateTotals();
}
}
private void Dg_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if ((dg.Columns[dg.CurrentCell.ColumnIndex].Name == "Choices") &&
(dg.IsCurrentCellDirty))
{
dg.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
}
private void CalculateTotals()
{
var totalPointsGained = dg.Rows.Cast<DataGridViewRow>()
.Where(a => a.Cells["PointsGained"].Value?.ToString() != "NA")
.Sum(a => Convert.ToInt32(a.Cells["PointsGained"].Value));
var totalPointsAvailable = dg.Rows.Cast<DataGridViewRow>()
.Where(a => a.Cells["PointsAvailable"].Value?.ToString() != "NA")
.Sum(a => Convert.ToInt32(a.Cells["PointsAvailable"].Value));
lblTotalPointsGained.Text = "Total Points Gained: " + totalPointsGained;
lblTotalAvailable.Text = "Total Points Available: " + totalPointsAvailable;
}
You can put the code I have in MyInitializeComponent() wherever you initialize your other objects on the form.

How To Add/Remove Items in c# Console Application Menu

I'm wondering if I could use a few simple dictionaries to store the data behind this or if I need something more... Need a system to be able to add and remove items and have that translated to other menus (methods). Sorry if this is worded poorly
public int AddProducts(int customerIDinput)
{
//If the order already has 5 products then display an error that no more products can be added
//Prompts the user for a product ID
//If the user selects an invalid product then display an error
//If the user selects a product that is discontinued then display an error
//Prompt the user for a quantity
//If the user enters a value < 1 or > 100 then display an error
//Add the product and quantity to the order
//Display the updated order information
//Return to the main menu
int input;
input = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Please eneter a product ID:");
switch (customerIDinput)
{
case 1
break;
case 2
break;
case 3
break;
case 4
break;
case 5
break;
}
return customerIDinput;
}
You can use a generic List and switch the value entered by the user to be the INDEX Value of that list of products
a quick Example :
List<String> Products = new List<string>();
int Value = Int.Parse(Console.ReadLine());
switch(Value)
{
case 1:
if (Products.Item(1) == null)
Console.WriteLine("Doesnt Exist!"); // This check will be in all cases in the Default one of caus
break;
}
Or you can use that check in the first for example :
List<String> Products = new List<string>();
int Value = Int.Parse(Console.ReadLine());
if (Products.Items(Value) == null)
{
//Display Error
}
else
{
switch(Value)
{
case 1:
//what u want here
break;
}
}

Switch statement on elements in list

Can I make a dynamics switch statement, i.e if I have a list containing 1,2,3,4,5 rather than manually doing case 1:, case 2: etc can I do it using a for loop as shown below?
The code doesn't work. Visual Studio gives an error saying case has to be a referenced label, I am a beginner.
switch (selectedShow)
{
//Show list is a list of type Shows
for (int i = 0; i < showList.Count; i+=1)
{
case i:
{
waitingList[waitingList.Count].Show = showList[selectedShow];
break;
}
}
}
It kinda seems you just want:
waitingList[waitingList.Count].Show = showList[selectedShow];
Switch statement is used for making a different operations for different values. thats why the "case" select the value to proceed. In your example only one operation is implemented for any value in your list. So, you don't need to apply "if" statement to check the condition where selectedShow is equal to some item in your list. Preferred way to iterate over list in C# is foreach operation. For example:
foreach (var i in showList)
{
if(i == selectedShow)
{
waitingList.Last().Show = i;
break;
}
}
I also replaced unsafe waitingList.[waitingList.Count] for more clear waitingList.Last() method (you may need to add using System.Linq; at the top of your file)
As already specified, you do not need a case statement. You can write a code similar to the following:
//Show list is a list of type Shows
for (int i = 0; i < showList.Count; i+=1)
{
waitingList[waitingList.Count].Show = showList[i];
if (someBreakConditionFunction())
break;
}
This code segment here:
//Show list is a list of type Shows
for (int i = 0; i < showList.Count; i+=1)
{
case i:
{
waitingList[waitingList.Count].Show = showList[i];
break;
}
}
makes no sense, for every value of i you will execute the case condition:
instead do:
for (int i = 0; i < showList.Count; i+=1)
{
waitingList[waitingList.Count].Show = showList[i];
}
switch (selectedShow)
{
//Show list is a list of type Shows
for (int i = 0; i < showList.Count; i+=1)
{
waitingList[waitingList.Count].Show = showList[i];
//Add some condition if you want to break the loop.
if(breakCondition)
break;
}
}
Using a forloop and if statement should work. I can iterate through the list using the for each loop and if the selected show (user selects in terminal) is the current iterated show. Then I can reference the show in the waitingList.
selectedShow = int.Parse(Console.ReadLine());
//Show list is a list of type Shows
for (int i = 0; i <=showList.Count;)
{
if (selectedShow == i)
{
//Count starts from 1 not 0
waitingList[waitingList.Count-1].Show = showList[selectedShow];
break;
}
}

C# Windows Forms how to change values of second combo box based on selection in first combo box

I am attempting to create an order form and as such am using combo boxes in order to let the user choose what item is going to be ordered. As such when the user selects the item that is going to be ordered, the second combo box should change to the sizes that the specific item can be ordered in. I have filled the second combo box with the sizes for all the items but I am unsure as to how to limit the sizes per the item that is selected. I have tried using if statements to addRange to the second combo box however this just duplicates the items at the end of the combo box. any help that can be given on this would be greatly appreciated. Thanks
private void itemBox_SelectedIndexChanged(object sender, EventArgs e)
{
switch (((ComboBox)sender).SelectedItem as string)
{
case "Name in a Frame":
sizeBox.SelectedIndex = 0;
break;
case "Scrabble Frame":
sizeBox.SelectedIndex = 1;
break;
case "Plaque":
sizeBox.SelectedIndex = 2;
break;
case "Hearts":
sizeBox.SelectedIndex = 3;
break;
case "Now and Forever Print":
sizeBox.SelectedIndex = 4;
break;
case "Pat cushion":
sizeBox.SelectedIndex = 5;
break;
case "Emilia cushion":
sizeBox.SelectedIndex = 6;
break;
}
}
private void sizeBox_SelectedIndexChanged(object sender, EventArgs e)
{
if (sizeBox.SelectedIndex == 0)
{
this.sizeBox.Items.AddRange(new object[]{
"7x5",
"10x8",
"A4",
"Mug"
});
}
}
You could just populate the sizeBox collection directly from the itemBox selected change event handler and remove sizeBox_SelectedIndexChanged altogether.
However, to achieve what, you need to clear the items in the sizeBox once the item has been selected. You can achieve this via:
sizeBox.Items.Clear();
You can then add the items once the sizeBox selected index has changed. I would simply use:
sizeBox.Items.Add("New Size");
For good practice I would remove the use of magic strings, maybe put them in a Products helper class that returns the appropriate string.

How can I utilize Polymorphism with List objects?

Here's a brief overview of my following problem, in case I am approaching this incorrectly:
I have a list of customers, purchase orders, and invoices all displayed in datagrids. I would like to verify that what is displayed in these grids matches the lists I actually have (this is for an automated testing application). The way I am trying to handle it, is by going through each table, and within that going through each row of objects, and comparing it to the objects in my lists (hence the actual/expected variables).
I have an application that has multiple List objects, for example:
List<PurchaseOrder>
List<Customer>
List<Invoice>
And I want to be able to write a loop that can manipulate each of these lists, rather than having one foreach statement for each list. I have multiple tables that show each object (a PO table, a customer table, etc) and I want to iterate all of them as such:
foreach(Table t in Tables)
{
List<??> tableItems = new List<??>; // Perhaps this should be `object tableItems;`?
switch(t.Name)
{
case "PurchaseOrder":
tableItems = purchaseOrders; // purchaseOrders is a List<PurchaseOrder> object
break;
case "Customer":
tableItems = customers; // List<Customer>
break;
case "Invoice":
tableItems = invoices; // List<Invoice>
break;
default:
break;
}
// Now I want to get the count of items, to loop through
for(int i = 0; i < tableItems.Count; i++)
{
// Do work
}
}
However, I can't figure out the right way to use the polymorphism here. If I make tableItems a List of Objects (List<Object>), I will get the error Cannot convert type of List<PurchaseOrder> to List<Object>.
If I cast tableItems to the Object class, I can't call the .Count field.
EDIT: I understand I could solve this easily by putting my for loop inside each case statement -
case "PurchaseOrder":
tableItems = purchaseOrders;
for(int i = 0; i < tableItems.Count; i++)
{
// Do Work
}
break;
But I would like a way to extract that for loop.
EDIT 2
Here's another example of the code I'm using now and what I would like to do with it but can't quite figure out:
foreach(Table t in Tables)
{
List<??> tableItems = new List<??>; // Perhaps this should be `object tableItems;`?
string expectedItem;
string actualItem = t.rows[currentRow].Cells[column1].Value.ToString();
switch(t.Name)
{
case "PurchaseOrder":
for(int i = 0; i < purchaseOrders.Count; i++)
{
PurchaseOrder p = purchaseOrders[i];
expectedItem = p.POValue1;
}
break;
case "Customer":
for(int i = 0; i < customers.Count; i++)
{
Customer c = customers[i];
expectedItem = c.CustValue1;
}
break;
case "Invoice":
for(int i = 0; i < invoices.Count; i++)
{
Invoice inv = invoices[i];
expectedItem = inv.InvoiceValue1;
}
break;
default:
break;
}
// I would prefer to do something like this:
switch(t.Name)
{
case "PurchaseOrder":
actualItem = purchaseOrders; // List<PurchaseOrder> object
break;
case "Customer":
actualItem = customers; // List<Customer>
break;
case "Invoice":
actualItem = invoices; // List<Invoice>
break;
default:
break;
}
for(int i = 0; i < tableItems.Count; i++)
{
(object) o = tableItems[i];
switch(object)
{
case "PurchaseOrder":
expectedItem = o.POValue1;
break;
case "Customer":
expectedItem = o.CustValue1;
break;
case "Invoice":
expectedItem = inv.InvoiceValue1;
break;
default:
break;
}
}
}
Instead of intermingling code that handles all tables simultaneously, I would solve the problem one table at a time.
Each object type dictates what is displayed in the table. This will always be a tuple of any kind of objects. So it is sufficient if the validation method gets these display objects instead of the source:
//More or less pseudo code
bool Validate(Table table, object[][] displayObjects)
{
for each iItem
for each iColumn
if(table.Rows[iItem].Columns[iColumn].Equals(displayObjects[iItem][iColumn])
//everything is fine
else
//there is a validation error
}
This leaves us with the task to transform any list of objects to its respective list of display objects. This can be performed with LINQ:
Validate(POTable, POList.Select(po =>
new object[] { po.Property1, po.Property2, po.Property3 }).ToArray());
// ...
OP. This seems like an XY question here. Your domain problem is that you would like to automate comparing a DataSet with a collection of collections of objects. You have noted that there are commonalities in the code for comparing PurchaseOrders with the PurchaseOrder table and Invoices with the Invoice table. I suggest you read up on design patterns and see if there is a pattern that would work with your problem.
The Strategy pattern looks to be pretty good for it...
public bool TableCollectionCompare<T>(
Compare<DataRow, T> comparer,
DataTable table,
ICollection<T> objects);
Another pattern would be an abstract class to do the loading of the Table and the collection...
public abstract class TableCollectionComparer<T>
{
protected bool Compare(DataRow row, T item);
public bool Compare(DataTable table, ICollection<T> item)
{
foreach(DataRow row in table.Rows)
{
...
bool result = Compare(row, item);
}
}
}

Categories