I have a program where you can enter data into text boxes in a tab control, then save the information you enter for later use. I have an 'Add tab' button, so I can add new tabs and enter new data, unfortunately when I click on the new tab and then go back to the previous tab my saved data in the previous tab has disappeared.
When I close the program and re run it, my data is there again, it is only when I navigate between tabs that my tab data disappears.
How do I make sure my data stays saved when I navigate between tabs?
Here is my add tab button code to give you a better understanding
int seasonYear = 12;
TabPage newTP = new TabPage();
tabControl1.TabPages.Add(newTP)
int TabPageNumber = tabControl1.SelectedIndex + 1; // +1 one up from current
tabControl1.TabPages[TabPageNumber].Text = "Season " + (12 - TabPageNumber);
txtPosition.Clear();
txtPoints.Clear();
txtWon.Clear();
txtDrawn.Clear();
txtLost.Clear();
tabControl1.SelectTab(TabPageNumber);
btnRemovetab.Enabled = true; // We now have something to delete
panel1.Parent = tabControl1.SelectedTab;
ShowData();
}
Related
While working on a small app that pulls test cases, runs, and results from an SQL Server Database, I encountered a dilemma in my methodology for attempting to create dynamic controller names in a TableLayoutPanel in WinForms. I am creating the rows dynamically when the user chooses the particular test case, and from there the TableLayoutPanel will open another window with the test steps preloaded and two radio buttons to indicate whether or not the test passed. My issue is that when I select one of the radio buttons on the right of the step, I get the same console read every single time. I need to be able to determine which exact radio button the user has pressed so I can therefore determine what row it's in and subsequently what test either passed or failed. My main code is as follows:
FormManualTest.cs (section when adding to the TableLayoutPanel)
private void addRowToolStripMenuItem_Click(object sender, EventArgs anotherEvent)
{
tableLayoutTest.RowStyles.Clear(); // Clear row styles to ensure a clean start when adding to the TableLayoutPanel
List<RadioButton> listOfRadioControls = new List<RadioButton>(); // Create array of radio buttons
List<UserCustomStep> listOfStepControls = new List<UserCustomStep>(); // Create array of custom controls
for (int i = 0; i < 5; i++)
{
UserCustomStep step = new UserCustomStep(Counter, "Step: " + i + " Push the button to elicit a response."); // Creates new user custom step control instance
RadioButton pass = new RadioButton();
pass.Text = "Pass";
pass.AutoSize = true;
RadioButton fail = new RadioButton();
fail.Text = "Fail";
fail.AutoSize = true;
fail.Margin = new Padding(3,3,20,3); // Needed to see the fail button without having to scroll over
listOfStepControls.Add(step); // Add step to UserCustomStep array
listOfRadioControls.Add(pass); // Add radio buttons to the RadioButton array
listOfRadioControls.Add(fail);
listOfRadioControls[i * 2].CheckedChanged += (s, e) => // Subscribes the pass radio button to listen for when a user has clicked on it
{
Console.WriteLine("Pass " + i + " was clicked");
};
listOfRadioControls[(i * 2) + 1].CheckedChanged += (s, e) => // Subscribes the fail radio button to listen for when a user has clicked on it
{
Console.WriteLine("Fail " + i + " was clicked");
};
tableLayoutTest.Controls.Add(listOfStepControls[i], 0, i); // Adds CustomStep to first column
tableLayoutTest.Controls.Add(listOfRadioControls[i*2], 1, i); // Adds Pass Radio Button to second column
tableLayoutTest.Controls.Add(listOfRadioControls[(i * 2) + 1], 2, i); // Add Fail Raido Button to third column
Counter++; // Increment couter to add subsequent steps underneath the previous ones.
}
}
Screenshots of App with Console Readout:
After Test Case Has Been Clicked and Radio Button Has Been Pressed
(From clicking this I would expect the console to read "Pass 1 was clicked")
Console Read:
Click Fail Button:
(I know from this image below that since the Pass button doesn't remain clicked I'm somehow using the same controller for all 5 of them)
Console Read
So from all of these issues that I've been presented with, I know that I'm somehow using the same controller for all 5 instances regardless of the fact that I'm storing everything in a controller array and grabbing from there. The for loop will have to be converted to a for each loop later, but that still doesn't solve my issue. I believe that if I could say something like:
RadioButton (pass+id) = new RadioButton();
or something similar while looping through to dynamically create the name for the controls, then each one would be a completely separate control and I could go from there. Any help would be greatly appreciated! I come from a heavy web background so my normal skills to remedy this in JS land aren't coming in handy as of right now. Thanks again for the assistance.
The Name property is optional, you don't need to specify it and it doesn't need to be unique. You can use property Tag for your own purpose (you can assign there ID or event instance of some object).
However you can also create your own control/usercontrol which encapsulate the whole row, and you can declare your own properties exactly for your purpose.
Background
I have a table of items that the user can edit. They can navigate through the fields with the arrow keys, and the information in the current row is saved when they move to a new one. The project requires a notification be displayed to the user when the row was successfully saved, and my boss requires me to do this through Bootstrap alerts.
One alert needs to be created for each successful save, and if the user saves multiple rows in a short time they should stack inside of a panel. Because the number of alerts is unknown, I'm dynamically adding them to the page from the code-behind. Each alert is made up of a panel and a label, which is being added to a larger panel that holds all the alerts. This part I've got figured out -- the alerts show up when they're supposed to, and in the correct numbers.
The problem is that each alert is only supposed to show on the screen for a limited amount of time. This is somewhere between two and five seconds, to be determined by my boss at a later date. My idea was to start a timer for two seconds each time an alert is created, and remove the first alert from the panel when the timer finished. Because no two timers would be created at exactly the same time, this should theoretically remove each alert two seconds after it appears, stopping once the last alert is gone. Unfortunately for me, that isn't how it's working.
Instead, I get an 'index out of bounds' exception, indicating that the alert I'm trying to remove doesn't actually exist. But it does exist -- I can see it on my screen. So I'm not sure what's going wrong.
Code
Creation of Alerts
This code is inside of Page_Load, so that the alerts are still visible on postback.
if (Session["success"] != null)
{
int test = Convert.ToInt32(Session["success"]);
for(int a = 1; a <= test; a++)
{
Panel alert = new Panel();
alert.CssClass = "alert alert-success";
alert.ID = "dynamicAlert" + a;
alert.Attributes["role"] = "alert";
Label innerAlert = new Label();
innerAlert.ID = "dynamicAlertInner" + a;
innerAlert.Text = "<strong>Success!</strong> Your row was saved.";
alert.Controls.Add(innerAlert);
alertsUpdate.ContentTemplateContainer.FindControl("pnlAlerts").Controls.Add(alert);
System.Timers.Timer time = new System.Timers.Timer(2000);
time.Elapsed += removeAlert;
time.Start();
}
}
Deletion of Alerts
The removeAlert method is intended to remove the alert at index 0 from the panel contained within the update panel.
private void removeAlert(Object source, System.Timers.ElapsedEventArgs e)
{
Panel pnl = (Panel)alertsUpdate.ContentTemplateContainer.FindControl("pnlAlerts");
if(pnl != null && pnl.Controls.Count > 0)
{
pnl.Controls.RemoveAt(0);
}
}
I am dynamically creating buttons in C# with this logic
for (int i = 1; i <= vap; ++i)
{
newButtons[i] = new Button();
newButtons[i].BackColor = Color.Gray;
newButtons[i].Name = "Button4" + i.ToString();
newButtons[i].Click += new EventHandler(NewButtons_Click);
newButtons[i].Location = new System.Drawing.Point(width,height);
newButtons[i].Size = new System.Drawing.Size(76, 38);
tabPage5.Controls.Add(newButtons[i]);
}
This is creating a button and the click event is also working but my problem is I don't know how to get the text of the newly created button. On form load I am putting the text of button from database and this also happening correctly, but I want to know how to get the text of dynamically created buttons.
You won't be able to get the text until after you populate it from the database (careful not to try and get the text too early).
But this should work:
string buttonText = FindControl("Button41").Text;
Update
Since you want the button text from within the click event, you can access the sender object:
Button button = sender as Button;
string buttonText = button.Text;
You just have to set the Text property of the button when you add it.
Using something along the lines of...
string BtnTxt = FindControl("ExampleButton1").Text;
should work fine.
This may cause problems later on however if you are trying to pull text content of buttons in a random order.
I am working on a web browser project I want to make a web browser I used ToolStrip to put all the functions of the web browser(favorite, history, home, GO, back, forward). What I want now is to make tha Tabs.
1) what do you think the best way to implement the tabs is it TabControl or is there another way.
2) how do I make to click on a label next to each tab and I open the new tab with a label next to it. So I can open a third one and so on.
I found this code, but it does not add dynamically and it add the second tab with leaving the label on the first tab
this.tabControl1.SelectedTab = tabPage2;
1) i made a tabcontrol and deleted all the tabs in the form
2)i made a button look like a plus and one looks like a minus and added this code:
int Counter = 1;
this.tabControl1.TabPages.Add("Page " + Counter);
this.tabControl1.SelectTab(Counter - 1);
Counter = Counter + 1;
this will add a new tab with title page (1,2,3,4,..,n) and then i put a code when i press go to the specified Url:
RequestAndResponsHelper RS = new RequestAndResponsHelper(Url.Text);
StringBuilder s = new StringBuilder();
s = RS.GetRequest();//get the request from a different class
string HtmlString = s.ToString();
rtb = new RichTextBox();
rtb.AppendText(HtmlString);
rtb.Name = "RichText";
rtb.Dock = DockStyle.Fill;
this.tabControl1.SelectedTab.Controls.Add(rtb);
Ok, I hope I can explain this well enough.
I have one or more third party Up/Down Spinner+Textbox controls on my page that are black boxes that I can't change the source for.
I want the user to change the UpDownControl contents to choose a quantity and then click a calendar button which will:
Add the quantity of all Up/Down boxes.
Call a javascript popup to display a calendar with the count from step 1 in the url "...calendar.asp?qty=5".
My problem is getting the two steps to execute in the same click. As it stands I can click the button once and it counts
the items and adds them to the popup string and then I have to click it a second time to actually execute the JS popup window.
The code was originally written to "load up" the counts into a second button and then programmatically click it but that looks
like a popup to the browsers since the user didn't click that button.
Here is what I have so far that almost works --
On my page:
<asp:ImageButton ID="btnPrepCal" runat="server" Text="PrepCal" OnClick="btnPrepCal_Click" ImageUrl="~/images/Calendar.gif"/>
In code behind:
public void btnPrepCal_Click(object sender, EventArgs e)
{
StringBuilder sbParams = new StringBuilder();
int TotalQty = 0;
int basketItemCount = 0;
int rowIndex = 0;
string Sku = string.Empty;
foreach (GridViewRow varRow in VariantGrid.Rows)
{
int qnty = GetControlValue(varRow, "Quantity", 0);
if (qnty > 0)
{
basketItemCount++;
string optionList = (string)VariantGrid.DataKeys[rowIndex].Value;
ProductVariant variant = _VariantManager.GetVariantFromOptions(optionList);
if (variant != null)
{
BasketItem basketItem = GetBasketItem(optionList, varRow);
if (basketItem != null)
{
TotalQty += basketItem.Quantity;
Sku = variant.Sku;
}
}
}
rowIndex++;
}
if(Sku.Length > 4) Sku = Sku.Substring(0,4);
sbParams.Append(string.Format("?sku={0}&Qty={1}", Sku, TotalQty));
string popup = string.Empty;
popup = string.Format("window.open('http://trustedtours.org/store/egalaxycalendar.asp{0}','Reservation Calendar','width=265,height=465')",sbParams.ToString());
btnPrepCal.OnClientClick = popup;
}
I'm new to .NET and web programming so I'm probably going at it totally backwards so any help is appreciated. I apologize if it's not clear what I'm trying to do or how. If you need any more info please ask - the rest of the file is a lot of shopping cart mumbo jumbo so I left it out, I hope it's enough.
---- update ----
After looking at the referenced pages I get:
Type cstype = this.GetType();
ClientScriptManager cs = Page.ClientScript;
StringBuilder cstext1 = new StringBuilder();
cstext1.Append("<script type=text/javascript>" + popup + "<script>");
cs.RegisterStartupScript(cstype, "PopupCalendar", cstext1.ToString());
And I believe this is added after I set the value of popup near the bottom of my Click handler above, removing the OnClientClick part, right?
Should this popup the other window on a page reload after clicking the button? (I hate being a newb and asking what's probably obvious questions.)
You can accomplish what you're aiming for using the ClientScriptManager.RegisterStartupScript method. Instead of assigning the OnClientClick method of the button to your JS popup code, set that code to run when the page is reloaded using the RegisterStartupScript method.
This page has some good examples: http://dotnetslackers.com/articles/aspnet/JavaScript_with_ASP_NET_2_0_Pages_Part1.aspx
Ken is correct. To add to his answer and clarify why your code was not working - you were assigning the click-handler of your button to do a popup, but only after it was clicked. This is why you only saw the popup after the 2nd click - the handler was not there the first time you clicked it.