The error message keeps popping up. Also, when I running the codes, it seems it's not working at all. I'm trying passing data to another page. Any suggestion?
This is the main page code,
public partial class _Default : System.Web.UI.Page
{
static int numBeachBookingInt = 0;
static int numBushBookingInt = 0;
static decimal totRevenue = 0;
protected void Page_Load(object sender, EventArgs e)
{
string totalRevenue;
if (Convert.ToString(Session["confirmBooking"]) == "confirm" && Convert.ToString(Session["bachType"]) == "bush")
{
totalRevenue = (string)(Session["totalRevenue"]);
totRevenue += decimal.Parse(totalRevenue);
totRevenueLabel.Text = String.Format("{0:c}", totRevenue);
numBushBooking += 1;
numBushHouseLabel.Text = numBushBooking.ToString();
Session["confirmBooking"] = "no current booking";
Session["bachType"] = "none";
}
else if (Convert.ToString(Session["confirmBooking"]) == "confirm" && Convert.ToString(Session["bachType"]) == "beach")
{
totalRevenue = (string)(Session["totalRevenue"]);
totRevenue += decimal.Parse(totalRevenue);
totRevenueLabel.Text = String.Format("{0:c}", totRevenue);
numBeachBooking += 1;
numBeachHouseLabel.Text = numBeachBooking.ToString();
Session["confirmBooking"] = "no current booking";
Session["bachType"] = "none";
}
numBeachHouseLabel.Text = numBeachBooking.ToString();
numBushHouseLabel.Text = numBushBooking.ToString();
this is the second.
protected void confirmButton_Click(object sender, EventArgs e)
{
Session["confirmBooking"] = "confirm";
Session["totalRevenue"] = totalRateLabel.Text;
switch (bachTypeRadioButtonList.Text)
{
case "Beach":
Session["bachType"] = "beach";
break;
case "Bush":
Session["bachType"] = "bush";
break;
default:
Session["bachType"] = "none";
break;
}
Response.Redirect("MainBookingForm.aspx");
}
It's hard to know what you're exact problem is without a stack trace. However, based on Googling "Format exception was unhandeled by user code", it's likely that one of the decimal.Parse(totalRevenue); statements is the problem. Since the string value of totalRevenue is set from totalRateLabel.Text, I wouldn't be surprised if that label has special characters (like a dollar sign) that you need to remove first.
Related
So in this class, I'm trying to use a switch statement to determine which radio button is checked in the form.
This is the part of the code that I'm focused on
private void lstTransactions_SelectedIndexChanged(object sender, EventArgs e)
{
int index = lstTransactions.SelectedIndex;
if (index != -1)
{
txtAmount.Text = entries[index, 0];
txtDate.Text = entries[index, 1];
chkCleared.Checked = bool.Parse(entries[index, 3]);
// entries[index, 2] is transaction type
//make switch comparison work correctly
// to determine which radio button should be checked
switch(entries[index, 2])
{
case TransactionTypes.Deposit.ToString():
rbDeposit.Checked = true;
break;
case TransactionTypes.Withdrawal.ToString():
rbWithdrawal.Checked = true;
break;
default:
rbServiceFee.Checked = true;
break;
}
}
}
Typing case TransactionTypes.Deposit.ToString(): and case TransactionTypes.Withdrawal.ToString(): gives me an error that says "CS0150 A constant value is expected". I tried looking up the error and I still can't figure out how to make the switch comparison work.
Here's the full Forms Code for Reference
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Transaction3
{
public partial class CheckbookForm : Form
{
public CheckbookForm()
{
InitializeComponent();
}
enum TransactionTypes { Deposit, ServiceFee, Withdrawal }
TransactionTypes transactionType;
private string[,] entries = new string[20, 4];
decimal balance = 0m;
decimal bankBalance = 0m;
private void SetError(Control whichControl, string message)
{
errorProvider1.SetError(whichControl, message);
}
private decimal IsValid()
{
bool flag=true;
decimal amount = 0m;
DateTime date;
if (DateTime.TryParse(txtDate.Text,out date))
{
if (date>DateTime.Today)
{
flag=false;
SetError(txtDate,"Date must be on or before today");
}
}
else
{
flag=false;
SetError(txtDate,"Date must be entered");
}
if (decimal.TryParse(txtAmount.Text, out amount))
{
if (amount<=0)
{
flag=false;
SetError(txtAmount,"Amount must be more than zero");
}
}
else
{
flag = false;
SetError(txtAmount,"Amount must be a number more than zero");
}
if (flag)
{
if (transactionType == TransactionTypes.Withdrawal)
{
if (balance >= amount)
{
amount *= -1;
}
else
{
flag = false;
SetError(txtAmount, "Insufficient funds");
}
}
else if (transactionType == TransactionTypes.ServiceFee)
amount *= -1;
}
if (!flag)
amount = 0;
return amount;
}
private void ShowBalance()
{
lblBalance.Text = balance.ToString("c");
lblBankBalance.Text = bankBalance.ToString("c");
}
private void ClearForm()
{
txtAmount.Clear();
txtAmount.Focus();
txtDate.Clear();
rbWithdrawal.Checked = true;
}
private void CheckbookForm_Load(object sender, EventArgs e)
{
rbDeposit.Tag = TransactionTypes.Deposit;
rbWithdrawal.Tag = TransactionTypes.Withdrawal;
rbServiceFee.Tag = TransactionTypes.ServiceFee;
ClearForm();
ShowBalance();
}
private void btnProcess_Click(object sender, EventArgs e)
{
errorProvider1.Clear();
decimal amount = IsValid();
if (amount != 0)
{
string entry;
string process = "Not Processed";
balance += amount;
if (chkCleared.Checked)
{
bankBalance += amount;
process = "Processed";
}
ShowBalance();
int row = lstTransactions.Items.Count;
entries[row, 0] = amount.ToString();
entries[row, 1] = txtDate.Text;
entries[row, 2] = transactionType.ToString();
entries[row, 3] = chkCleared.Checked.ToString();
entry = string.Format("{0} {1}: {2} ({3})", transactionType.ToString(),
txtDate.Text, amount.ToString("c"), process);
lstTransactions.Items.Add(entry);
}
}
private void btnClear_Click(object sender, EventArgs e)
{
ClearForm();
}
private void btnReset_Click(object sender, EventArgs e)
{
errorProvider1.Clear();
DialogResult button;
button = MessageBox.Show("Clear all prior entries and set balance to $0?\nThis CANNOT be undone.",
"Reset Account", MessageBoxButtons.YesNo);
if (button == System.Windows.Forms.DialogResult.Yes) {
balance = 0;
bankBalance = 0;
ClearForm();
ShowBalance();
lstTransactions.Items.Clear();
}
}
private void btnExit_Click(object sender, EventArgs e)
{
this.Close();
}
private void rb_CheckedChanged(object sender, EventArgs e)
{
RadioButton rb = (RadioButton)sender;
if (rb.Checked)
transactionType = (TransactionTypes) rb.Tag;
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
btnExit_Click(sender, e);
}
private void CheckbookForm_FormClosing(object sender, FormClosingEventArgs e)
{
DialogResult button;
button = MessageBox.Show("Close and exit? All entries will be lost.",
"Exit?", MessageBoxButtons.OKCancel, MessageBoxIcon.Question,
MessageBoxDefaultButton.Button2);
if (button == System.Windows.Forms.DialogResult.Cancel)
e.Cancel = true;
}
private void lstTransactions_SelectedIndexChanged(object sender, EventArgs e)
{
int index = lstTransactions.SelectedIndex;
if (index != -1)
{
txtAmount.Text = entries[index, 0];
txtDate.Text = entries[index, 1];
chkCleared.Checked = bool.Parse(entries[index, 3]);
// entries[index, 2] is transaction type
//make switch comparison work correctly
// to determine which radio button should be checked
switch(entries[index, 2])
{
case TransactionTypes.Deposit.ToString():
rbDeposit.Checked = true;
break;
case TransactionTypes.Withdrawal.ToString():
rbWithdrawal.Checked = true;
break;
default:
rbServiceFee.Checked = true;
break;
}
}
}
}
}
You should ditch the multidimensional array and go with a typed List or Array.
Multidimensional arrays are useful when the data is of the same type, yours it a bit of everything. so we in turn would make a class.
public class Entry
{
public Entry(decimal amount, DateTime date, TransactionType transactionType, bool cleared)
{
Amount = amount;
Date = date;
TransactionType = transactionType;
Cleared = cleared;
}
public decimal Amount { get; set; }
public DateTime Date { get; set; }
public TransactionType TransactionType { get; set; }
public bool Cleared { get; set; }
}
Given
// now an array of Entry
private Entry[] entries = new Entry[20];
Usage
To update update an entry
// add / update and array slot
entries[row] = new Entry(amount, DateTime.Parse(txtDate),transactionType,chkCleared.Checked);
Your switch would look like this
switch (entries[index].TransactionType)
{
case TransactionTypes.Deposit:
rbDeposit.Checked = true;
break;
case TransactionTypes.Withdrawal:
rbWithdrawal.Checked = true;
break;
default:
rbServiceFee.Checked = true;
break;
}
Note : This is not meant to be a working example, or to make your code work, it was merely showing you how you could used a typed array to make your life easier and show a potential for the switch without having to parse your string back into an enum
Alternatively you could just use Enum.Parse
Converts the string representation of the name or numeric value of one
or more enumerated constants to an equivalent enumerated object.
var tranType = (TransactionTypes)Enum.Parse(typeof(TransactionTypes), entries[index, 2]);
switch(tranType)
The error you are facing, has nothing to do with multidimensional arrays. It is due to using a runtime value inside a case logic.
You cannot use case TransactionTypes.Withdrawal.ToString() as a case statement. The last part ToString() is a function call. Even though it will always return the same value, the compiler does not know that. It will always think that the value of case TransactionTypes.Withdrawal.ToString() is not known at compile time, and thus is a potential risk for runtime error and thus will not compile.
You might wanna think what is the harm in having a runtime value. Consider the following code -
switch (entries[index].TransactionType)
{
case TransactionTypes.Withdrawal.ToString()://only known at wexecution not before that
throw a;
break;
case TransactionTypes.Withdrawal.ToString()://only known at wexecution not before that
throw b;
break;
default:
break;
}
Both the cases have same values. But the compiler cannot determine them unless it executes the code and when it will try to do that, there will be a clash in the decision. To save the code for such failure, having dynamic value in a switch-case is prohibited and that is the reason for that exception.
In future the compilers might be more intelligent to determine proper branching based on codes, but for now we are stuck with constant values for cases. So remove the function call or use Enum.Parse to get the enum values and do your check. Something like this -
if(Enum.TryParse<TransactionTypes>(entries[index, 2], true, out TransactionTypes parsed){
switch (parsed)
{
case TransactionTypes.Deposit://constant value, no issue
rbDeposit.Checked = true;
break;
case TransactionTypes.Withdrawal://constant value, no issue
rbWithdrawal.Checked = true;
break;
default:
rbServiceFee.Checked = true;
break;
}
}
else{
throw new Exception("Unknonw enum string");
}
get more details about Enum.Parse or Enum.TryParse here https://learn.microsoft.com/en-us/dotnet/api/system.enum.tryparse?view=netframework-4.8
I am currently having trouble understanding Methods and how they work in C#. I currently have code written for a car cost calculator program I created, I want to rearrange or break my code down using methods. I am unsure how or where to begin doing so as it pertains to my program. Here is my code, clarification would be helpful! Thank you!
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//constants for the Zone entered by user
const decimal ZoneCostN = 27;
const decimal ZoneCostS = 36;
const decimal ZoneCostE = 45;
const decimal ZoneCostW = 54;
private void CalcButton_Click(object sender, EventArgs e)
{
//set the variables
decimal PackWeight = 0;
decimal CostZone = 0;
decimal CostWeight = 0;
decimal ShippingTot = 0;
decimal Net = 0;
const decimal PerPound = 18;
//parses the entry into the textboxes
decimal.TryParse(WeightText.Text, out PackWeight); ;
//algorithm for variables
CostWeight = PackWeight * PerPound;
Zonelbl.Text = "";
CostZone = 0;
//if else statement to get the zone cost
{
if (NorthButton.Checked)
{
CostZone = ZoneCostN;
}
else if (SouthButton.Checked)
{
CostZone = ZoneCostS;
}
else if (EastButton.Checked)
{
CostZone = ZoneCostE;
}
else if (WestButton.Checked)
{
CostZone = ZoneCostW;
}
else
{
MessageBox.Show("Select a zone!");
}
}
//algorithm to get total and net
ShippingTot = CostZone + CostWeight;
Net = ShippingTot / CostWeight;
//if condition for CAPPED label
if (ShippingTot >= 100)
{
CAPPEDlbl.Visible = true;
}
else
{
CAPPEDlbl.Visible = false;
}
//output for all the data
Zonelbl.Text = CostZone.ToString("c");
Weightlbl.Text = CostWeight.ToString("c");
Totallbl.Text = ShippingTot.ToString("c");
Netlbl.Text = Net.ToString("c");
}
private void ClearButton_Click(object sender, EventArgs e)
{
//clears the form
Zonelbl.Text = "";
Weightlbl.Text = "";
Totallbl.Text = "";
Netlbl.Text = "";
WeightText.Text = "";
CAPPEDlbl.Visible = false;
WeightText.Focus();
}
}
Usually, we create methods when we need to reuse a code. In your case, you should see which part of your code will be reused in the future. If it is a simple form you may don't need to change anything but imagine you want to use your clear functionality somewhere else, create a method and call it everywhere you need
void clear()
{
Zonelbl.Text = "";
Weightlbl.Text = "";
Totallbl.Text = "";
Netlbl.Text = "";
WeightText.Text = "";
CAPPEDlbl.Visible = false;
WeightText.Focus();
}
private void ClearButton_Click(object sender, EventArgs e)
{
clear();
}
Now you can reuse clear() and in case you needed to change it you only need to change the method. It's the concept and you can apply it wherever you need.
I'm geting a StackOverflowException. Somehow, posting here seemed appropriate.
I'm using Windows Forms in a C# application. This application is intended to run on Linux, FreeBSD and Mac-OS, so I can't use WPF, so please don't suggest it.
My guess is that I'm missing a nuance of WinForms, but I cant seem to figure out what.
The ComboBox is generated by the GUI form builder in VS 2010.
The specific lines of code that are throwing the error are here:
if(cur_num_is_valid)
{
cbx_material_num.Text = num;
}
else
{
num = "0";
//I only have one of the following two at a time. Both overflow
cbx_material_num.SelectedIndex = 0;
cbx_material_num.Text = "0";
}
Since the code is somewhat complex, here's the whole function code. 'cbx_' indicates a combo box. 'txtb_' is a text box.
private void cbx_material_numobj_SelectedIndexChanged(object sender, EventArgs e)
{
string obj = cbx_material_obj.Text;
string num = cbx_material_num.Text;
int selnum = 0;
int n = 0;
//do we need to recreate the numbers array?
bool cur_num_is_valid = false;
cbx_material_num.Items.Clear();
if(obj != lastobj)
{
n = m_demo.get_object_modifiers(obj);
for(int i = 0; i <= n; i++)
{
string s = i.ToString();
if(s == num && i < n) cur_num_is_valid = true;
cbx_material_num.Items.Add(s);
}
}
if(cur_num_is_valid)
{
cbx_material_num.Text = num;
}
else
{
num = "0";
//Overflow here:
cbx_material_num.SelectedIndex = 0;
}
try
{
selnum = int.Parse(num);
}
catch(Exception)
{
MessageBox.Show("Error, second select menu after 'object modifiers' must be a number, not '"+num+"'.");
cbx_material_num.Text="0";
return;
}
if(selnum >= n)
{
txtb_material_param1.Text = "0";
txtb_material_param2.Text = "0";
txtb_material_param3.Text = "0";
txtb_material_param4.Text = "0";
}
else
{
MaterialFace face;
MaterialParameter parameter;
int typeid;
object paramdata;
m_demo.get_object_modifiers_material(obj, selnum, out face, out parameter, out typeid, out paramdata);
cbx_material_face.Text = face.ToString();
cbx_material_paramtype.Text = parameter.ToString();
switch(typeid)
{
case 0:
txtb_material_param1.Text = ((float)paramdata).ToString();
cbx_material_datatype.Text = "float";
goto case -1;
case 1:
float[] parsf = ((float[])paramdata);
txtb_material_param1.Text = parsf[0].ToString();
txtb_material_param2.Text = parsf[1].ToString();
txtb_material_param3.Text = parsf[2].ToString();
txtb_material_param4.Text = parsf[3].ToString();
cbx_material_datatype.Text = "float[]";
break;
case 2:
txtb_material_param1.Text = ((int)paramdata).ToString();
cbx_material_datatype.Text = "int";
goto case -1;
case 3:
int[] parsi = ((int[])paramdata);
txtb_material_param1.Text = parsi[0].ToString();
txtb_material_param2.Text = parsi[1].ToString();
txtb_material_param3.Text = parsi[2].ToString();
txtb_material_param4.Text = parsi[3].ToString();
cbx_material_datatype.Text = "int[]";
break;
case -1: //can't actuall be returned, used to 'blank' the last three as '0'
txtb_material_param2.Text = "0";
txtb_material_param2.Text = "0";
txtb_material_param3.Text = "0";
break;
case 4:
OpenTK.Graphics.Color4 paramc = ((OpenTK.Graphics.Color4)paramdata);
txtb_material_param1.Text = paramc.R.ToString();
txtb_material_param2.Text = paramc.G.ToString();
txtb_material_param3.Text = paramc.B.ToString();
txtb_material_param4.Text = paramc.A.ToString();
cbx_material_datatype.Text = "Color4";
break;
default: //5
Vector4 paramv = ((Vector4)paramdata);
txtb_material_param1.Text = paramv.X.ToString();
txtb_material_param2.Text = paramv.Y.ToString();
txtb_material_param3.Text = paramv.Z.ToString();
txtb_material_param4.Text = paramv.W.ToString();
cbx_material_datatype.Text = "Vector4";
break;
}
}
}
You need to check that the SelectedIndex isn't already 0 before you try to set it:
if (cbx_material_num.SelectedIndex != 0){
cbx_material_num.SelectedIndex = 0;
}
Otherwise you're re-firing the event every time through.
I think that whenever you set this cbx_material_num.SelectedIndex = 0; within the EventHandler you invoke your
cbx_material_numobj_SelectedIndexChanged(object sender, EventArgs e)
Each call invokes another eventHandler so the stack fills up after some time.
Basically, the fact that it is called SelectedIndexChanged doesn't mean that the value has to be different from the previous one but that the value is set through its setter.
I am trying to preserve the page state when i go to another page, but for some reason when i go back to this page, the items are returned to their default state. Why doesn't it work? It seems to follow the tutorials perfectly...
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
State["Title"] = TitleTextBox.Text;
//all of those are RadioButtons - if their is a better way to do it then please comment :)
int i = new int();
if (RB0.IsChecked.Value)
i = 0;
else if (RB1.IsChecked.Value)
i = 1;
else if (RB2.IsChecked.Value)
i = 2;
else if (RB3.IsChecked.Value)
i = 3;
State["CheckedRB"] = i;
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (State.ContainsKey("Title"))
TitleTextBox.Text = State["Title"] as string;
if (State.ContainsKey("CheckedRB"))
{
int i = (int)State["CheckedRB"];
if (i == 0)
RB0.IsChecked = true;
else if (i == 1)
RB1.IsChecked = true;
else if (i == 2)
RB2.IsChecked = true;
else if (i == 3)
RB3.IsChecked = true;
}
}
Edit: I traced the problem by adding breakpoints.
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
State["Title"] = TitleTextBox.Text;
string look0 = WorkOutName.Text;
string look = State["WorkOutName"] as string;
int i = new int();
if (RB0.IsChecked.Value)
i = 0;
else if (RB1.IsChecked.Value)
i = 1;
else if (RB2.IsChecked.Value)
i = 2;
else if (RB3.IsChecked.Value)
i = 3;
State["CheckedRB"] = i; <-------- breakpoint
and here are the results:
(OnNavigatedFrom)
look0 : "Text From TextBox"
look1 : "Text From TextBox"
i : (0, 1, 2, or 3)
and same with OnNavigatedTo:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (State.ContainsKey("Title"))
TitleTextBox.Text = State["Title"] as string; <--breakpoint
if (State.ContainsKey("CheckedRB"))
{
int i = (int)State["CheckedRB"]; <--breakpoint
if (i == 0)
RB0.IsChecked = true;
else if (i == 1)
RB1.IsChecked = true;
else if (i == 2)
RB2.IsChecked = true;
else if (i == 3)
RB3.IsChecked = true;
}
}
and Neither one of them (on OnNavigatedTo) go off.
I tried your code and it seems to work fine. I don't know if this is your case, but remember that if you have the following navigation flow in the app:
Page1 (forward navigation)-> Page2 (back navigation)-> Page1 (forward navigation)-> Page2
If you saved the state in Page2 when first visiting it, that state will NOT be preserved when returning to Page2 again, this is because when doing a back navigation the page is discarded and so is the state dictionary for that page. You can read more about that in the documentation.
I have this program that I am working on for class, I think the problem is in my if statements. When I run the program and make my selection and click the total button and I get this as a display "for your appetizer, for your entree, and for dessert" in the order label and the price for the steak dinner in the order total label. I think I may have to use switch statements, but I'm not sure any suggestions would be of great help, thanks.
namespace Restaurant
{
public partial class frmRestaurant : Form
{
decimal AppetizerPrice = 0.0m;
decimal EntreePrice = 0.0m;
decimal DessertPrice = 0.0m;
decimal total = 0.0m;
string AppetizerOrder = "", EntreeOrder = "", DessertOrder = "", order = "";
public frmRestaurant()
{
InitializeComponent();
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void btnTotal_Click(object sender, EventArgs e)
{
CalculateTotal();
Order();
lblOrder.Text = order;
lblTotal.Text = total.ToString();
}
private void grpAppetizer_Enter(object sender, EventArgs e)
{
if (radCheeseSticks.Checked)
{
AppetizerPrice = 5.99m;
AppetizerOrder = "Cheese Sticks";
}
else if (radGarlicBread.Checked)
{
AppetizerPrice = 4.50m;
AppetizerOrder = "Garlic Bread";
}
else if (radChipsnSalsa.Checked)
{
AppetizerPrice = 3.50m;
AppetizerOrder = "Chips and Salsa";
}
}
private void grpEntree_Enter(object sender, EventArgs e)
{
if (radSteakDinner.Checked)
{
EntreePrice = 12.50m;
EntreeOrder = "Steak Dinner";
}
else if (radChickenParm.Checked)
{
EntreePrice = 10.99m;
EntreeOrder = "Chicken Parmigiana";
}
else if (radChipsnSalsa.Checked)
{
EntreePrice = 3.50m;
EntreeOrder = "Chips and Salsa";
}
}
private void grpDessert_Enter(object sender, EventArgs e)
{
if (radSteakDinner.Checked)
{
DessertPrice = 12.50m;
DessertOrder = "Steak Dinner";
}
else if (radChickenParm.Checked)
{
DessertPrice = 10.99m;
DessertOrder = "Chicken Parmigiana";
}
else if (radChipsnSalsa.Checked)
{
DessertPrice = 3.50m;
DessertOrder = "Chips and Salsa";
}
}
public decimal CalculateTotal()
{
total = AppetizerPrice + EntreePrice + DessertPrice;
return total;
}
public string Order()
{
order = AppetizerOrder + "for your appetizer," + EntreeOrder + "for your entree, and " + DessertOrder + "for dessert";
return order;
}
}
}
I think the GroupBox.Enter event is not useful for your use case. The enter event is invoked sometime during the control activation, but not when the value is changed.
One way to fix your problem is to set the appetizer/entree/dessert price and text only when the "Total" button is clicked. You do not need it before that in the current form right now.
Another way to fix it is to use the correct event: Just handle the RadioButton.CheckedChanged event for all of those radio buttons, for example:
private void radGarlicBread_CheckedChanged(object sender, EventArgs e)
{
if (radGarlicBread.Checked)
{
AppetizerPrice = 4.50m;
AppetizerOrder = "Garlic Bread";
}
}
First of all, you probably want to use String.Format(), because it'll look a bit cleaner than a bunch of concatenation--it'll also help you catch things like the lack of spaces here (your output seems like it would be, e.g. 'Chips and Salsafor your appetizer...')
It might also be better to just find whichever item is checked in the Order method rather than update it every time the user checks.
I'm not sure what is wrong, but maybe you can do a Debug.WriteLine() every time each of the Enter() methods is called to see what is going on.
For example:
Debug.WriteLine("grpDesert_Enter");
Debug.WriteLine(radSteakDinner.Checked);
Debug.WriteLine(radChickenPark.Checked);
Debug.WriteLine(radChipsnSalsa.Checked);