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.
Related
I would like to redo the code of my old windows forms application on wpf and I have a problem with referencing datagridview.
This is the void look of my old application:
private void button2_Click(object sender, EventArgs e)
{
if (DGV1.Rows.Count > 0 && DGV1.SelectedRows != null)
{
bool wart = true;
for (int i = 0; i < listBox2.Items.Count; i++)
{
listBox2.SelectedIndex = i;
int w1 = Int32.Parse(listBox2.SelectedItem.ToString());
int w2 = Int32.Parse(DGV1.SelectedRows[0].Cells[0].Value.ToString());
if (w1 == w2)
{
wart = false;
break;
}
}
if (wart)
{
listBox2.Items.Add(DGV1.SelectedRows[0].Cells[0].Value);
}
}
}
This is the void look of my new application:
private void Button1_Click(object sender, RoutedEventArgs e)
{
IList rows = dataGrid1.SelectedItems;
if(dataGrid1.SelectedItem != null)
{
bool wart = true;
for (int i =0; i < listBox1.Items.Count; i++)
{
listBox1.SelectedIndex = i;
object item = dataGrid1.SelectedItem;
int w1 = Int32.Parse(listBox1.SelectedItem.ToString());
int w2 = Int32.Parse(dataGrid1.SelectedCells[0].Column.GetCellContent(item).ToString()); <--- !!
if(w1 == w2)
{
wart = false;
break;
}
}
if(wart)
{
listBox1.Items.Add(dataGrid1.SelectedCells[0]); <-- !!
}
}
}
The application spills out at the second if, where it displays:
And it should be:
Please Help :-)
It should probably be like this:
listBox1.Items.Add(dataGrid1.CurrentRow.Cells[0].Value);
This code is from WinForms, but I assume the coding for wpf may not be different, since both are in c#.
dataGrid1.SelectedItem isn't just some object, it has concrete type and properties like Id, Tytul, Kategorie, Text
you need to make a cast to that concrete type and access property instead of trying to get the value from low-level UI elements like DataGridCellInfo:
var item = (MyConcreteClass)dataGrid1.SelectedItem;
int w2 = item.Id;
I'm building a web application using a webform and I'm trying to store a counter in a Session, but I'm getting the error that if(!IsPostback) doesn't exist in the current context. Can anyone help me with this issue?
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostback)
{
Session["AttemptCount"] = 0;
}
}
protected void submitAnswerButton_Click(object sender, EventArgs e)
{
//difficultyList.SelectedIndex = 2;
answerStatus.Visible = true;
int answer = randomNumber1 + randomNumber2;
int counter = (int)Session["AttemptCount"];
if (mathAnswerTextBox.Text == answer.ToString())
{
counter++;
Session["AttemptCount"] = counter;
answerStatus.Text = "Correct!";
// scoreLabel.Text = "Score: " + counter.ToString();
randomNumber1 = random.Next(0, 50);
randomNumber2 = random.Next(0, 50);
num1Label.Text = Convert.ToString(randomNumber1);//add this line
num2Label.Text = Convert.ToString(randomNumber2); //and this line
num1Label.Visible = true;
num2Label.Visible = true;
mathAnswerTextBox.Visible = true;
submitAnswerButton.Visible = true;
}
else if (mathAnswerTextBox.Text != answer.ToString())
{
answerStatus.Text = "Incorrect";
incorrectStrikes.Text = counter.ToString();
num1Label.Visible = true;
num2Label.Visible = true;
mathAnswerTextBox.Visible = true;
submitAnswerButton.Visible = true;
// scoreLabel.Text = counterArray[0].ToString();
}
As I previously mentioned in my comment to your question, your original problem was with the lowercase b in Postback. The reason your "AttemptCount" session variable is not being incremented is because your if statement only increments it:
if (mathAnswerTextBox.Text == answer.ToString())
I think you want to do this in the else clause of your if statement, and not when the answer is correct.
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.
Just learning C# (along with object and event programing) and the teacher didn't really show us how to get things done.
class Postion
{
private int[] x_coordinate = new int[100];
private int[] y_coordinate = new int[100];
private double[] speed = new double[100];
private int[] direction = new int[100];
const int MAX_SPEED = 50;
int counter = 0;
public Postion()
{
x_coordinate[counter] = 0;
y_coordinate[counter] = 0;
speed[counter] = 0;
direction[counter] = 0;
}
//get set methods
public int X
{
get
{
return x_coordinate[counter];
}
set
{
x_coordinate[counter] = value;
}
}
There is one more Class between them
The values are frist assigned by a button click.
Airplane newplane = new Airplane();
private void BtnCreate_Click(object sender, EventArgs e)
{
bool box = txtName.Text != "";
if (box == true)
newplane.Name = txtName.Text;
else { }
box = txtx.Text != "";
if (box == true)
newplane.PlanePostion.X = int.Parse(txtx.Text);
else { }
Etc.
I can call on the array values for display for the list box.
private void lsbplanes_SelectedIndexChanged(object sender, EventArgs e)
{
placeholder = newplane.PlanePostion.Counter;
newplane.PlanePostion.Counter = lsbplanes.SelectedIndex;
if (newplane.PlanePostion.Counter < 0)
newplane.PlanePostion.Counter = 0;
else { }
lblxshow.Text = Convert.ToString(newplane.Getx());
but when using a destroy button to remove an item in the list box I need to have it so the box updates with the new values when the user selects the item in the listbox.
This is what I have to try and do it so far, it sets all the ones above to 0s but does remove the the deleted one fine
private void BtnKill_Click(object sender, EventArgs e)
{
if (lsbplanes.SelectedIndex == -1)
{
MessageBox.Show("Please select an item first.", "No item selected", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
else
{
placeholder = lsbplanes.SelectedIndex;
newplane.PlanePostion.Counter = lsbplanes.Items.Count;
while (newplane.PlanePostion.Counter > placeholder)
{
placex = newplane.PlanePostion.X;
placey = newplane.PlanePostion.Y;
placespeed = newplane.Getspeed();
placedic = newplane.Getdirection();
newplane.PlanePostion.Counter--;
newplane.PlanePostion.X = placex;
newplane.PlanePostion.Y = placey;
newplane.PlanePostion.Speed = placespeed;
newplane.PlanePostion.Direction = placedic;
}
lsbplanes.Items.RemoveAt(lsbplanes.SelectedIndex);
newplane.PlanePostion.Counter = lsbplanes.Items.Count;
}
anyone can help me on this?
I was torn in this question, answer exactly what your problem is, or suggest that you redesign it.
#Marc is right you should be using some sort of List<Position> on your Plane object (or a ReadOnlyObservableCollection<Position>).
#Marc is also right, that the problem you are having is that you are trying to push the values down from the end of the list and overwriting them. In these cases it is better to start from the deletion point and pull them down.
So if you have {1,2,3,4,5,6,7,8,9,10} and you delete from item 5, you would have {1,2,3,4,10,10,10,10,10,10}. The code below will let you end up with {1,2,3,4,6,7,8,9,0}
placeholder = lsbplanes.SelectedIndex;
int idx = placeholder;
while (idx < lsbplanes.Items.Count)
{
newplane.PlanePosition.Counter = idx+1;
placex = newplane.PlanePostion.X;
placey = newplane.PlanePostion.Y;
placespeed = newplane.Getspeed();
placedic = newplane.Getdirection();
newplane.PlanePostion.Counter = idx;
newplane.PlanePostion.X = placex;
newplane.PlanePostion.Y = placey;
newplane.PlanePostion.Speed = placespeed;
newplane.PlanePostion.Direction = placedic;
idx++;
}
// Need to zero out elements at the end
newplant.PlanePosition.Counter = lsbplanes.Items.Count;
/* Zeroing code goes here */
newplane.PlanePosition.Counter = placeholder;
lsbplanes.Items.RemoveAt(lsbplanes.SelectedIndex);
How do I do this in a loop.
protected void ddlTool_SelectedIndexChanged(object sender, EventArgs e)
{
lblTool1.Visible = false;
txtTool1.Visible = false;
lblTool2.Visible = false;
txtTool2.Visible = false;
lblTool3.Visible = false;
txtTool3.Visible = false;
lblTool4.Visible = false;
txtTool4.Visible = false;
lblTool5.Visible = false;
if (ddlTool.SelectedValue == "1")
{
lblTool1.Visible = true;
txtTool1.Visible = true;
}
if (ddlTool.SelectedValue == "2")
{
lblTool1.Visible = true;
txtTool1.Visible = true;
lblTool2.Visible = true;
txtTool2.Visible = true;
}
if (ddlTool.SelectedValue == "3")
{
lblTool1.Visible = true;
txtTool1.Visible = true;
lblTool2.Visible = true;
txtTool2.Visible = true;
lblTool3.Visible = true;
txtTool3.Visible = true;
}
if (ddlTool.SelectedValue == "4")
{
lblTool1.Visible = true;
txtTool1.Visible = true;
lblTool2.Visible = true;
txtTool2.Visible = true;
lblTool3.Visible = true;
txtTool3.Visible = true;
lblTool4.Visible = true;
txtTool4.Visible = true;
}
Instead of having a separate variable for each textbox and label, have a collection of them - whether that's a List<T> or an array or whatever.
Then you can do:
// Potentially use int.TryParse here instead
int visibleLabels = int.Parse(ddlTool.SelectedValue);
for (int i = 0; i < labels.Count; i++)
{
labels[i].Visible = (i < visibleLabels);
textBoxes[i].Visible = (i < visibleLabels);
}
(Alternatively use two loops, one to set some Visible properties to true, and one to set some to false.)
You can access a control by its name using
container.Controls["nameofcontrol"]
So technically, you could use this to lookup your control
(Untested code)
for(int index = 1; index <= Convert.ToInt32(ddlTool.SelectedValue); index++)
{
this.Controls["lblTool" + index.ToString()].Visible = true;
this.Controls["txtTool" + index.ToString()].Visible = true;
}
Use a UserControl for each set of connected controls and then enable/disable the UserControl instead of all the component controls. This is classic, basic modularization of your user interface.
Note that this will still require a little "redundant" code because you're working with an unusual UI paradigm by enabling up-to the ddlTool's selected value of your control. E.g., create your user control that contains a single Label and TextBox. Call it LabeledTextBox or something similar. Then you'd create a collection of your labeled text boxes and enable them up to int.Parse(ddlTool.SelectedValue) - 1.
foreach (Control ctrl in this.Controls)
{
int index = (int)ctrl.Name.Substring(ctrl.Name.Length - 1);
int maxIndex = (int)ddlTool.SelectedValue;
ctrl.Visible = (index <= maxIndex);
}
Here is an example with no error checking, but should match your code functionality.
protected void ddlTool_SelectedIndexChanged(object sender, EventArgs e)
{
int selectedValue = int.Parse(ddlTool.SelectedValue.ToString());
for (int i = 1; i <= 4; ++i)
{
bool state = i <= selectedValue;
this.Controls["lblTool" + i.ToString()].Visible = state;
this.Controls["txtTool" + i.ToString()].Visible = state;
}
}