ASP.Net using RadioButtonList / CheckBoxList - c#

I am finishing up a program for my ASP.Net class for an ice cream shop done as a web app, the main page looks like THIS. I need two classes for the Ice Cream ordering:
IceCreamOrder
IceCreamOrderList
currently the only code in my IceCreamOrderList class is
public class IceCreamOrderList
{
List<IceCreamOrder> ICorders = new List<IceCreamOrder>();
public List<IceCreamOrder> ListofOrders { get { return ICorders; } }
public void Add(IceCreamOrder data) { ICorders.Add(data); }
and nothing in the IceCreamOrder class. My code on/around the Submit Order button IS
I've done a simpler program that was just taking text entered into a textbox and adding to a list, but my biggest problem is figuring out how to determine what control is set to true and then add them into a list. I have names for each of the controls as follows:
FlavorsList
ToppingsList
ServeList
Any help and guidance toward finishing this would be most greatly appreciated. and Thanks in advance

If you already using RadioButtonList and CheckBoxList into your order page, you should change event handler btnSubmit_Click as follows:
protected void btnSubmit_Click(object sender, EventArgs e)
{
IceCreamOrder order = new IceCreamOrder();
order.Flavor = FlavorsList.SelectedValue;
foreach (ListItem listItem in ToppingsList.Items)
{
if (listItem.Selected)
order.Toppings.Add(listItem.Value);
}
order.Serve = ServeList.SelectedValue;
// add order to order list
}
public class IceCreamOrder
{
public string Flavor { get; set; }
public List<string> Toppings { get; set; }
public string Serve { get; set; }
public IceCreamOrder()
{
Toppings = new List<string>();
}
}

Related

DataGridView Showing Empty Rows when assigned to a List of Type containing internal properties

I experienced an issue which kind of opposed my basic C# concepts on Access Modifiers. So i build a Sample application reproducing Same Scenario.
There is a Parent Form with Click Button on the event of which a new Form spawns with a DataGridView. The Data Source is static string,string and the properties are internal as i am using everything in the same project.
To my surprise, there were 5 rows made since i had 5 data items bind to that grid but were just empty Rows. Then i made the properties as public and i was able to get them. All the Rows were populated with correct Data the second Time.
Parent Form
namespace SampleApp{
public partial class Form1 : Form
{
List<ItemModel> modelList = new List<ItemModel>();
public Form1()
{
InitializeComponent();
}
private void btnClick_Click(object sender, EventArgs e)
{
LoadData();
using (SeperateWindow window = new SeperateWindow(modelList))
{
window.PopulateGrid();
if(window.ShowDialog() == DialogResult.OK)
{
}
}
}
public void LoadData()
{
for(int i= 0; i < 5; i++)
{
ItemModel item = new ItemModel($"Name { i}", i.ToString());
modelList.Add(item);
}
}
}
Model Class
namespace SampleApp.Model{
sealed class ItemModel
{
internal string Textvalue { get; set; }
internal string ID { get; set; }
internal ItemModel(string text,string id)
{
Textvalue = text;
ID = id;
}
}
Child Form Containing GridView
namespace SampleApp.Model{
public partial class SeperateWindow : Form
{
List<ItemModel> _modelList = new List<ItemModel>();
internal SeperateWindow(List<ItemModel> modelList)
{
_modelList = modelList;
InitializeComponent();
}
public void PopulateGrid()
{
dataGridView1.DataSource = _modelList;
}
}
My issue is since everything is in the same project, and model class and child form are in the same Folder too, then also why am i getting Empty Rows? Given that it is working fine if i make them public.
From MSDN
The properties you use as binding source properties for a binding must be public properties of your class. Explicitly defined interface properties cannot be accessed for binding purposes, nor can protected, private, internal, or virtual properties that have no base implementation.
Also please refer to this question, in which the difference between public and internal keywords in databinding has been discussed.

PropertyEventChangedHandler of ObservableCollections not firing

I've defined an Observable collection as shown below,
public class PropertyFieldsInExcel
{
public string LongNames { get; set; }
public string ShortNames { get; set; }
public string CNames { get; set; }
}
static ObservableCollection<PropertyFieldsInExcel> Properties =
new ObservableCollection<PropertyFieldsInExcel>();
I have a method which changes the the value of some of the elements in that class like so,
public static void AutofillCell()
{
((INotifyPropertyChanged)Properties).PropertyChanged +=
new PropertyChangedEventHandler(PropertyChangedEvent);
Properties[i].CNames = "It works";
Properties[i].CNames = "Ha ha ha";
((INotifyPropertyChanged)Properties).PropertyChanged -=
new PropertyChangedEventHandler(PropertyChangedEvent);
}
When I assign a value to a particular element as shown above, the event does not fire. Why? What is the mistake I've committed?
The code of the event handler is like so,
private static void PropertyChangedEvent(object sender, PropertyChangedEventArgs e)
{
//Some code to be executed
}
Two problems:
1) PropertyFieldsInExcel does not implement INotifyPropertyChanged
2) ObservableCollection can inform you when items are changing, but only after you manually subcribe to the changed event of all items.
The link in the comment from Uwe Keim gives an exellent explanation with examples...

C# UWP Undo button

Ok so i created an app to manage Score's for 2 teams. APP Layout. As you can see i have Team A and Team B, the 0 below adds the points for overall score, while below that you have a history of what points where earned each round.
when you press the go button the points from the 2 Textboxes go do the addition for all the score and add the points of that round in the lists.
As you can see i created an Undo button. so if for example i press the Go button by accident i can just tap on my undo button to undo button to undo my mistake. the thing is i don't know what code to write in the click event of undo button.
private void Undo_Click(object sender, RoutedEventArgs e)
{
}
Note: my lists are binded to a class i made. so each list displays the the property it needs through observablecollection.
class List
{
public int ListA { get; set; }
public int ListB { get; set; }
}
UPDATE:
private void Undo_Click(object sender, RoutedEventArgs e)
{
var lastState = Lists.Last();
int teamAScore, teamBScore, listA, listB;
// this way i got the Active scores.
int.TryParse(CurrentScoreA.Text, out teamAScore);
int.TryParse(CurrentScoreB.Text, out teamBScore);
// this way i got the last score that i want to remove.
listA = lastState.ListA;
listB = lastState.ListB;
// here i remove the last score from the Active one.
teamAScore = teamAScore - listA;
teamBScore = teamBScore - listB;
// And here i replace my Active score with
// the new one that has the last states removed.
CurrentScoreA.Text = teamAScore.ToString();
CurrentScoreB.Text = teamBScore.ToString();
// this one removes the last states of the list
// so this way i can always remove the last part of my lsit
// from both my active score and list till i go back to 0.
Lists.Remove(lastState);
}
Thnx a lot to the 2 guys that answered my questions below and by reading them and trying to execute them i found my solution!!!! :)
Pano,
you can create a List<List<List>>(sry your class names doesn't help) that each time the user adds a score you will hold the values in a list like a state. So when you click undo you pop the Last Item from the List of List and replace to your list. Here is an example
List<List<Score>> ScoreStates = new List<List<Score>>();
List<Score> Scores = new List<Score>();
private void Undo_Click(object sender, RoutedEventArgs e)
{
var lastState = ScoreStates.Last();
ScoreStates.Remove(lastState);
Scores = lastState;
}
public class Score
{
public int TeamA { get; set; }
public int TeamB { get; set; }
}
What i meant is:
class List
{
public int ListA { get; set; }
public int ListB { get; set; }
}
Then you create 2 objects of class List one to operate on and the other to keep like a previous state (but it duplicate your objects!!!)
and the button will be:
private void Undo_Click(object sender, RoutedEventArgs e)
{
ClassListObj1.ListA = ClassListObj2.ListA;
ClassListObj1.ListB = ClassListObj2.ListB;
}
or even, but I'm not sure...
private void Undo_Click(object sender, RoutedEventArgs e)
{
ClassListObj1 = ClassListObj2;
}
Remember, you'll have to do ClassListObj2.ListA = ClassListObj1.ListA; or ClassListObj2.ListB = ClassListObj1.ListB; before modifying the lists.
The idea with the struct is better, but it requires me to know more about your app, to elaborate.

How to pass through data from a child form into the parent form without refreshing the list

I am doing a school project in creating a POS system and i need to pass in through the same order list throughout the different form.The problem is everytime i return to the main menu, the list refreshes although i still need the data is there anyway to prevent this from happening?
public partial class Main : Form
{
List<string> order = new List<string>();
public Main()
{
InitializeComponent();
}
public Main(List<string> order)
{
InitializeComponent();
this.order = order;
}
this is the start code for the main menu
And this is the code to add the items from thelistbox to the list
private void confirmbtn_Click(object sender, EventArgs e)
{
order.AddRange(temp_order);
if (pendinglist.Items.Count != 0)
{
MessageBox.Show("Your Items have been added! yay!", "That Sushi", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("No items was selected.", "That Sushi", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
pendinglist.Items.Clear();
}
Thank you in advance for your help.Please let me know if anything else is wrong with the code too. again thank you for the help
You are probably closing the form and re-creating it every time you open it again, and since these orders are inside it, obviously the previous content is lost.
Solution : that list of orders should be outside main form
Here's a really simple pattern for you, it's really primitive but it works and should be enough/plausible for your homework : a static class
public static class MyModel
{
public static Order Order { get; set; }
public static void NewOrder()
{
Order = new Order();
}
}
public class Order
{
public Order()
{
Products = new List<Product>();
}
public List<Product> Products { get; set; }
public void AddProduct(Product product)
{
Products.Add(product);
}
}
public class Product
{
public string Name { get; set; }
public decimal Price { get; set; }
}
And here's how you'd use it from a form:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void buttonNewOrder_Click(object sender, EventArgs e)
{
MyModel.NewOrder();
}
private void buttonAddProduct_Click(object sender, EventArgs e)
{
var product = new Product();
product.Name = "PS4";
product.Price = 1000000000.0m;
MyModel.Order.AddProduct(product);
}
private void buttonShowProductsInOrder_Click(object sender, EventArgs e)
{
var order = MyModel.Order;
var products = order.Products;
var builder = new StringBuilder();
foreach (var product in products)
{
var format = string.Format("Name: {0}, Price: {1}", product.Name, product.Price);
builder.AppendLine(format);
}
MessageBox.Show(builder.ToString());
}
}
Order will not vanish and will be accessible from many forms.
Obviously it's a pretty bad practice, gurus would use MVP (model view presenter), MVC (model view controller) or whatever pattern along a database behind, but there's little point to roll out such design for your question. You can/should take a look at what these concepts are, however.
Good luck !

WPF and C#: Trouble with Classes and Interfaces

I'm working on a bank account program. I'm using a base class, an interface, and two derived classes in addition to my main window class. I am making a WPF application, and so far I am able to populate a ListBox with an ArrayList of class objects in that app just fine. However, when I go to modify any of the objects in the ArrayList, I'm running into difficulty repopulating the ListBox correctly. Any help will be greatly appreciated!
This is my MainWindow code:
public partial class MainWindow : Window
{
ArrayList bankAccountList = new ArrayList();
BankAccount savingsAccount = new SavingsAccount("New", "Account", "newaccount");
BankAccount checkingAccount = new CheckingAccount("New", "Account", "newaccount");
IAccount iAccount;
string typeOfAccount = "";
public MainWindow()
{
InitializeComponent();
}
//When the user pushes the "Add A Saving Account" button, a new savings account is added to the ArrayList and displayed in the app.
private void btnAddAccount_Click(object sender, RoutedEventArgs e)
{
iAccount = (IAccount)savingsAccount;
savingsAccount.Deposit(0.00m);
bankAccountList.Add(savingsAccount);
lbxExistingAccounts.Items.Add(iAccount.AccountInformation());
typeOfAccount = "savings";
}
//When the user pushes the "Add A Checking Account" button, a new checking account is added to the ArrayList and displayed in the app.
private void btnAddCheckingAccount_Click(object sender, RoutedEventArgs e)
{
iAccount = (IAccount)checkingAccount;
checkingAccount.Deposit(0.00m);
bankAccountList.Add(checkingAccount);
lbxExistingAccounts.Items.Add(iAccount.AccountInformation());
typeOfAccount = "checking";
}
//When the user pushes the "Delete Account" button, the account is removed, and this change is shown in the app.
private void btnDeleteAccount_Click(object sender, RoutedEventArgs e)
{
lbxExistingAccounts.Items.RemoveAt(lbxExistingAccounts.Items.IndexOf(lbxExistingAccounts.SelectedItem));
}
//The user can push the "Submit Changes" button to submit his or her changes to the number and name of the account.
private void btnSubmitChanges_Click(object sender, RoutedEventArgs e)
{
try
{
for (int index = 0; index < bankAccountList.Count; index++)
{
if (index == lbxExistingAccounts.SelectedIndex)
{
if (typeOfAccount == "savings")
{
savingsAccount.AccountNumber = tbxAccountNumber.Text;
savingsAccount.AccountOwnerFirstName = tbxFirstName.Text;
savingsAccount.AccountOwnerLastName = tbxLastName.Text;
}
else if (typeOfAccount == "checking")
{
checkingAccount.AccountNumber = tbxAccountNumber.Text;
checkingAccount.AccountOwnerFirstName = tbxFirstName.Text;
checkingAccount.AccountOwnerLastName = tbxLastName.Text;
}
}
}
lbxExistingAccounts.Items.Clear();
foreach (object accountObject in bankAccountList)
{
lbxExistingAccounts.Items.Add(accountObject);
}
}
catch (FormatException)
{
MessageBox.Show("You may enter changes as letters, numbers, or both.");
}
}
This is my Interface code:
interface IAccount
{
void SetAccountBalance(decimal accountBalance);
string AccountInformation();
}
This is my base class code:
abstract class BankAccount
{
public string AccountNumber { get; set; }
public string AccountOwnerFirstName { get; set; }
public string AccountOwnerLastName { get; set; }
public decimal AccountBalance { get; set; }
public decimal AnnualInteresetRate { get; set; }
public string TypeOfAccount { get; set; }
public BankAccount(string accountOwnerFirstName, string accountOwnerLastName, string accountNumber)
{
AccountOwnerFirstName = accountOwnerFirstName;
AccountOwnerLastName = accountOwnerLastName;
AccountNumber = accountNumber;
}
public abstract void Deposit(decimal amount);
public abstract void Withdraw(decimal amount);
public decimal CalculateInterest()
{
return (this.AccountBalance * this.AnnualInteresetRate) / 100;
}
}
This is one of my derived classes. I made both pretty much the same.
class SavingsAccount : BankAccount, IAccount
{
public SavingsAccount(string accountOwnerFirstName, string accountOwnerLastName, string accountNumber)
: base(accountOwnerFirstName, accountOwnerLastName, accountNumber)
{
AnnualInteresetRate = 0.95m;
}
public override void Deposit(decimal amount)
{
AccountBalance = AccountBalance + amount;
}
public override void Withdraw(decimal amount)
{
AccountBalance = AccountBalance - amount;
}
public void SetAccountBalance(decimal accountBalance)
{
AccountBalance = accountBalance;
}
public string AccountInformation()
{
return "Savings Account \n " + AccountOwnerFirstName + " " + AccountOwnerLastName + ", Account#: " + AccountNumber + ", Balance: $" + AccountBalance;
}
}
It looks like you are just starting out, which is good, because you are going to want to rework some things.
You don't need to cast your derived objects to their base types. This type of casting is called "upcasting" and automatically works without any casting whatsoever.
The code you posted is highly "WinForms-ish" and this is not a good approach in WPF. Start with making your account list an ObservableCollection and binding your ListBox's ItemsSource to it.
The property would look like:
public ObservableCollection<BankAccount> Accounts {get; set;}
Which should actually use INotifyPropertyChanged omitted for brevity, and the binding:
<ListBox "ItemsSource={Binding Accounts}"/>
Of course, that should go in a view model class, but you could start with your code-behind by setting:
DataContext = this;
Once that is working all your text boxes should be bound to properties of the data objects or of the view itself.
Here is a great tutorial on using MVVM with WPF (MSDN). Trust me, using this design pattern will make your work with WPF immensely easier, more extensible, and you will find that WPF was basically designed to use it. Using a WinForms approach is just going to cause you pain.
Please let me know if I can assist further or clarify anything!
I would recommend using ObservableCollection for your collection, so that any changes made to the items would be reflected visually without any additional work. It wouldn't require any significant changes. All you would do is switch your ArrayList for an ObservableCollection.
http://msdn.microsoft.com/en-us/library/ms668604(v=vs.110).aspx
I would also highly recommend implementation of INotiftyPropertyChanged interfrace for your objects, so that when account information is changed, appropriate subscribers are notified.
http://msdn.microsoft.com/en-us/library/vstudio/system.componentmodel.inotifypropertychanged
I've been using both of those extensively with my WPF applications.

Categories