for (int i = 0; i < service.journeys.Count; i++)
{
var popup = new JourneyPopup();
// Fill out the form
popup.txtJourney.Text = service.journeys[i].journeyCode;
popup.txtDays.Text = service.journeys[i].daysOfWeek;
popup.txtDeparture.Text = service.journeys[i].departureTime;
popup.txtOrigin.Text = service.journeys[i].description;
popup.Show();
}
Inside my JourneyPopup form I have a button called 'done'. I need to iterate the for loop only after 'done' has been clicked. How can I do this?
You might try the .ShowDialog() function. It will not return until the dialog/form has closed.
I assume that it's a WinForm application and JourneyPopup is derived from Form.
Then, in the Forms designer, you can give the button a custom int value, that will be returned by the Form.Show() methods when the button was pressed.
At the end of your loop, you then can check this:
if (popup.ShowDialog() != <Returnvalue from button>)
{
break;
}
Related
I want to get form which is open but hidden. I have tried by this. I get the form but in this case form show and hide within fraction of second. If I skip mfrm.Show(), I don't get MailSynchronize form in Application.OpenForms.
MailSynchronize mfrm = new MailSynchronize();
mfrm.Show();
mfrm.Hide();
I get form by following method.
foreach (Form f in Application.OpenForms) //it will return all the open forms
{
if (f.Name == "MailSynchronize")
{
mfrm = (MailSynchronize)f;
break;
}
}
Can anybody please suggest me how to get open form which is hidden by default and I can get in Application.OpenForms?
If I Hide a form, does it exist in Application.OpenForms?
No, unfortunately if you Hide a form, it will not be present in Application.OpenForms
So how can I open an invisible Form? Also I want it to exists in Application.OpenForms.
If you want to open an invisible Form, and you want it want it to exists in Application.OpenForms, you can use this code instead of simply Show():
var f = new MailSynchronize();
f.Opacity = 0;
f.ShowInTaskbar = false;
f.Show();
How to find that form again?
To get the open instance of form you can use Application.OfType<MailSynchronize>()
var f= Application.OpenForms.OfType<MailSynchronize>()
.FirstOrDefault();
When I found it, How to show it again?
f.Opacity = 1;
f.ShowInTaskbar = true;
f.Show();
How to hide it again?
You should not call Hide() to hide the form because it makes the form to get out of Application.OpenForms, instead you should use this way:
f.Opacity = 0;
f.ShowInTaskbar = false;
Is there another way?
Yes, for example you can create an static property in a class, for example in Program.cs this way:
public static MailSynchronize MailSynchronizeInstance { get; set; }
and the first time you want to open your form, you can assign the instance to this property, and then you can use it using Program.MailSynchronizeInstance to show or hide and you don't need to look in Application.OpenForms or perform a workaround.
Also you can make this property in a singletone way.
EDIT
This should work for your specific case now:
this.Opacity = 0;
this.ShowInTaskbar = false;
When you add these 2 codelines in your MailSynchronize constructor the form will start minimized but will not show in your taskbar, which is essentially the effect you were looking for. Also the form will now popup in your Application.OpenForms Collection.
When form initiallize.
MailSynchronize mfrm = new MailSynchronize();
mfrm.Opacity = 0;
mfrm.Show();
mfrm.Hide();
How to find that form again?
foreach (Form f in Application.OpenForms) //it will return all the open forms
{
if (f.Name == "MailSynchronize")
{
mfrm = (MailSynchronize)f;
break;
}
}
When I found it, How to show it again?
mfrm.Opacity = 1;
mfrm.Show();
Hide again by Button.
mfrm.Hide(); //It will not show form in Application.OpenForms if I hide again by mfrm.Opacity = 0;
use f.Visible (return type is bool)
if it returns false, it means form is hidden. If it returns true then form is visible.
I have my main form and a dialogbox which is called from main. In my main form I have a label and a button that which properties I can't change. I'm using Visual Studio 2015, not sure if there is a bug regarding this. I also made sure my label and button are set to public to modify.
Code: (this is from the dialog box, this has a list box the function is triggered at selectindexchange)
else if ((short)lbDiscountTypes.SelectedValue == 2) //Senior
{
frm_Main main = new frm_Main();
main.VAT = false;
main.labelStatus.Text = "NON-VAT (SENIOR)";
main.labelStatus.BackColor = System.Drawing.Color.IndianRed;
main.labelStatus.ForeColor = System.Drawing.Color.WhiteSmoke;
main.btnNonVat.Enabled = false;
main.btnNonVat.BackColor = System.Drawing.Color.SlateGray;
main.btnNonVat.ForeColor = System.Drawing.Color.Navy;
main.labelVatAmount.Text = 0.00m.ToString();
main.Dispose();
//INQUIRE DISCOUNT TYPES
var Discount = GC.CSHR_DiscountTypes.Where(Filter => Filter.DiscountCode == (short)lbDiscountTypes.SelectedValue);
decimal DP = 0.00m;
foreach (var item in Discount)
{
DP = item.DiscountPercentage;
}
foreach (var item in GC.CSHR_SORepo
.Where(Filter => Filter.Machine == MACHINE
&& Filter.SalesOrderNum == SALESORDERNUM
&& Filter.First_SRP == Filter.IMFSRP))
{
item.DiscountAmount = (item.SoldSRP * DP) / 100;
item.TotalAmount = (item.Quantity * item.SoldSRP) - item.DiscountAmount;
item.VATableSalesOnTotalAmount = (item.Quantity * item.SoldSRP) - item.DiscountAmount;
item.VATRate = 0.00m;
GC.SaveChanges();
}
Close();
}
The code below //INQUIRE DISCOUNT TYPES works well but not the one on top.
I've used debug mode to check if the lines are not being skipped over and they aren't.
You should pay attention to:
You are creating a new instance of your main form that you don't need (while it is open behind the dialog), so you need to get it not create a new instance
You are disposing the main form you created. main.Dispose();
In fact you are creating a new instance of main form and assigning values to those controls and then dispose it. While and instance of yor main form that you expect to see changes on it, is open and untouched behind your dialog.
To set value of those controls you can do one of these ways:
Option 1
Make your labelStatus and btnNonVat public. Open your main form in designer and select labelStatus and btnNonVat and in property grid, set Modifier to public. Then write this code:
//var main = Application.OpenForms.OfType<frm_Main>().FirstOrDefault();
var main = (frm_Main)Application.OpenForms["frm_Main"];
main.labelStatus.Text = "NON-VAT (SENIOR)";
main.labelStatus.BackColor = System.Drawing.Color.IndianRed;
main.labelStatus.ForeColor = System.Drawing.Color.WhiteSmoke;
main.btnNonVat.Enabled = false;
main.btnNonVat.BackColor = System.Drawing.Color.SlateGray;
main.btnNonVat.ForeColor = System.Drawing.Color.Navy;
main.labelVatAmount.Text = 0.00m.ToString();
Option 2
Pass an instance of your frm_Main to your dialog and work with it.
Option 3
After closing the dialog, use values from dialog and set values of your main form
Looks like you are trying to create new form using frm_Main main = new frm_Main(); syntax. All you need to do is get the instance of your current form.
var _currentMainForm= Application.OpenForms[0];
or if you have given name to your form
var _currentMainForm = Application.OpenForms["MainFormName"];
Once you get the reference you can perform all your label updates.
The code on top creates a new form, changes the labels and then disposes the form.
I think you should change the labels of the existing form.
Like in the other answer said you are setting properties of controls into a new Form object and not in the form where you come from.
You should pass the form object into the parameters of the dialog, something like:
void myDialog(frm_Main callingForm)
{
callingForm.Textbox1.Text = "abc";
}
And call it from you main form like this
...
myDialog(this);
Some inits done earlier in the code...
private List<System.Windows.Forms.TabPage> tab_pages = new List<System.Windows.Forms.TabPage>();
int tab_increment = 0;
Somewhere in the code, I create a bunch of tab pages in real-time.
for (i=0; i<5; i++)
{
tab_pages.Add( new System.Windows.Forms.TabPage() );
tab_pages[tab_increment].Location = new System.Drawing.Point(4, 22);
tab_pages[tab_increment].Name = 1 + tab_increment.ToString();
tab_pages[tab_increment].Size = new System.Drawing.Size(501, 281);
tab_pages[tab_increment].Text = tab_increment.ToString();
this.tabControl.Controls.Add(tab_pages[tab_increment]);
tab_increment += 1;
}
Now I would like to access elements that are these tab pages. Also let's pretend that I created different elements on each page (example, tabPage[0] a button, tabPage[1] a checkbox, etc), how do I access them knowing that everything was added dynamically?
Check this approach:
void Walk(Control control)
{
foreach (Control c in control.Controls)
{
//just walking through controls...
//...do something
//but remember, it could contain containers itself (say, groupbox or panel, etc.)...so, do a recursion
if (c.Controls.Count > 0)
Walk(c);
}
//or
foreach (Button btn in control.Controls.OfType<Button>())
{
//an example of how to walk through controls sub array of certain type
//this loop won't have a single iteration if this page contains no Buttons
//..so you can replace Button
//and have some certain code for different types of controls
}
}
And launch it for tabcontrol:
foreach (TabPage page in tabControl1.TabPages)
Walk(page);
I guess there is no special need to have separate collection of tabpages for one tabcontrol, as soon as it has TabPages property.
In the code above I used Enumerable.OfType Method to get a subcollection of controls of certain type.
As for your code, try this:
for (int i = 0; i < 5; i++)
{
this.tabControl.Controls.Add(new System.Windows.Forms.TabPage());
this.tabControl.TabPages[i].Text = i.ToString();
//...do whatever you need
//...
//besdies, I think, ther's no need in tab_increment...loop index works well enough
}
In order to add pages, I think that using
tabControl.TabPages.Add(new TabPage("Name"));
or in your case
this.tabControl.TabPages.Add(tab_pages[tab_increment]);
is more suitable.
In order to access them you could use
TabPage tp = tabControl.TabPages[i]; //where i is the index of your TabPage
and you can use TabPage.Controls.Add of the Controls property to add any Control on the TabPage like:
Button btn = new Button();
btn.Name = "Button name";
tp.Controls.Add(btn);
You can use the Controls property on the TabPage object. Each control in the collection is given to you as a Control, and it is up to you to cast them to the type that you want.
On one web user control
public void displayFindingSection(int sectionsid,string text,string head)
{
SectionHeading.Text = head;
DataSet totImgs;
totImgs = objGetBaseCase.GetFindingsNewerImages(sectionsid);
FindingViewerlist.DataSource = totImgs;
DataBind();
SectionText.Text = text;
}
On other web user control
public void DisplayFindingsViewer(CipCaseWorkflowItem2 item)
{
FindingViewerDisplay.Visible = true;
ImageAndSimpleViewer.Visible = false;
objGetBaseCase.GetFindingsImages((Convert.ToInt32(Session["CaseId"])), item.ItemId);
FindingsViewerNew = objGetBaseCase.GetFindingViewerNewElementDetails(item.ItemId);
for (int i = 0; i < FindingsViewerNew.Count; i++)
{
FindingViwerDisplay uc = (FindingViwerDisplay)LoadControl("FindingViwerDisplay.ascx");
FindingPlaceholder.Controls.Add(uc);
uc.displayFindingSection(Convert.ToInt32(FindingsViewerNew[i].Index), FindingsViewerNew[i].Text, FindingsViewerNew[i].Title);
}
}
I am adding the all the image in user control and displaying the image, but when i am using the above code, web user control is also adding every time and one image is showing in in control what i want is all images should show in only one user control.. sectionsid is getting the image id from the database. I think prob with for loop but i am unable to solve it.. help me it that
Might be it is happening u have defined it inside the loop
FindingViwerDisplay uc = (FindingViwerDisplay)LoadControl("FindingViwerDisplay.ascx");
FindingPlaceholder.Controls.Add(uc);
On Each loop you are adding uc and calling displayFindingSection whcich ofcouse add 1 image than loop go back add a new control again and than add one image it will go on till your loop completion so add control once before loop and call just displayFindingSection in loop..
Do this,
FindingViwerDisplay uc = (FindingViwerDisplay)LoadControl("FindingViwerDisplay.ascx");
FindingPlaceholder.Controls.Add(uc);
//define here a dataTabel with three columns let say u have datatable dt
for (int i = 0; i < FindingsViewerNew.Count; i++)
{
dt.Rows.Add(Convert.ToInt32(FindingsViewerNew[i].Index), FindingsViewerNew[i].Text, FindingsViewerNew[i].Title);
}
uc.displayFindingSection(dt);
Then work out on that dt in displayFindingSection
Sorry if i am wrong...
I have an input field on my page where the user will type in the number of text inputs they want to create. The action for the button is:
int num_flds = int.Parse(a_fld.Text);
for (int i = 0; i < num_flds; i++)
{
TextBox tmp = new TextBox();
tmp.ID = "answer_box" + i;
tmp.Width = Unit.Pixel(300);
answer_inputs.Controls.Add(tmp);
}
Now, I have another button that the user would click after they have filled in all their dynamically-created text boxes. Questions, first of all, am I creating the text boxes dynamically in the correct place? How would I get the values out of the dynamically-created text boxes? (The dynamically-created text boxes are being added to the Panel "answer_inputs".
I recommend reading this and a few other articles about the topic of dynamically created controls. It is not quite as straightforward as you might think. There are some important page lifecycle issues to consider.
When creating web controls dynamically, I find it best to have the controls themselves report in the answers. You can achieve it like this:
Create something in your Page class to store the values:
private readonly Dictionary<TextBox, string> values=new Dictionary<TextBox, string>();
Make a method to act as a callback for the textboxes when their value changes:
void tmp_TextChanged(object sender, EventArgs e)
{
TextBox txt = sender as TextBox;
if(txt!=null)
{
values.Add(txt,txt.Text);
}
}
And then add this method to each textbox as they are added:
int num_flds;
if(!int.TryParse(a_fld.Text,out num_flds))
{
num_flds = 0;
}
for (int i = 0; i < num_flds; i++)
{
TextBox tmp = new TextBox();
tmp.ID = "answer_box" + i;
tmp.Width = Unit.Pixel(300);
answer_inputs.Controls.Add(tmp);
tmp.TextChanged += tmp_TextChanged;
}
Finally, you iterate through the dictionary on callback to see if it holds any values. Do this in the OnPreRender method for instance.
Edit: There is a problem with this, if the number of text fields are decreased on postback. Some safe way to recreate the previous textfields on postback should be employed.