Add tabs to TabControl from another form - c#

This is freaking me out, and if this is possible I would gladly appreciate the help.
I am a C# developer but have to do this in VB.NET.
So C# answers accepted as well.
I have a tab control on a form. This control does not have any tabs in it yet.
When the form loads, it loads a "Start" page. It adds the tab "tbpStart" and loads a form onto the tab page "frmStart".
On this start page, I have many Radio Buttons. When I click on one radio button, it should load other tabs on the main form.
The problem is how can I add tabs to one form's tab control from another form?
CODE:
When Main Form loads:
Try
'Load the Start Tab
Dim start As New frmTabStart
AddTabPage("Start", start)
Catch ex As Exception
PMComponentLibrary.PMMessageBox.ShowErrorMessage("Error occurred while trying to load the from.", ex)
End Try
Function on Main Form:
Public Sub AddTabPage(tabPageName As String, myForm As System.Windows.Forms.Form)
Try
myForm.TopLevel = False
myForm.Dock = DockStyle.Fill
myForm.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None
Dim NewTab As New System.Windows.Forms.TabPage
NewTab.Name = "tab" + tabPageName
NewTab.Text = tabPageName
NewTab.Controls.Add(myForm)
tbcMain.TabPages.Add(NewTab)
myForm.Show()
Catch ex As Exception
Throw ex
End Try
End Sub
When I click on one Radio Button on "Start Form" it executes this on a click_event:
If sender Is rdbWIPPostings Then
entity = New frmTabEntity()
mainForm.AddTabPage("Step 1", entity)
Application.DoEvents()
dte = New frmTabDate()
mainForm.AddTabPage("Step 2", dte)
wipSelect = New frmTabWIPSelect()
mainForm.AddTabPage("Step 3", wipSelect)
finish = New frmTabFinish()
mainForm.AddTabPage("Finish", finish)
End If
But the tabs does not get added to the Main Form.
What am I doing wrong?

Modify the constructor for frmTabStart to receive an instance of mainForm like this:
public frmTabStart(MainForm mainForm)
{
// store that in a field
}
and then when you need to add the tab:
_mainForm.AddTabPage(...);

Related

Winforms TextBox keeps value in UserControl

I am making an app in which there are multiple UserControls stacked onto each other. So the elements go like this: MainForm -> User clicks on a UserControl1 on the MainForm which (UserControl1) has a panel on which there is displayed another UserControl2 with a button. When the user clicks on it, it displays another UserControl3 which is then displayed in the panel beneath the button, where finally the user enters some text in the textbox. I need the data from the textbox in the MainForm so I have MainForm and UserControls connected via EventHandlers and pass my ResponseModel in which there is some dat a that I need to pass to MainForm. The first time this works, an item is created and displayed, after the item there is this "button" (User controls) displayed, in case the user wants to create another one. But then comes the problem when the user types in a different text for a new item, it creates an item with the same text!! Like the textbox was never changed (I have a debugging point set on the constructor to see every time that the textbox is empty). Below is some code and an image, for you to see how this should work. Also when I first delete the item it then doesn't work to create a new item for some reason.
This is how I send the data from the last UserControl:
if (tbx_list_name.Text == "")
MessageBox.Show("You can't create new list without a name!", "Can't create new list!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
else
CreateListTextBoxHandler?.Invoke(this, new ListCreationResponseModel() {
Code = id, ListName = tbx_list_name.Text
});
This is how I create the last UserControl which has the textbox:
control.CreateListTextBoxHandler += GetHandlerData;
panel.Controls.Add(control);
And this is how I get the data one stage down (this practice continues through couple more stages back to MainForm):
public void GetHandlerData(object sender, ListCreationResponseModel e)
{
try
{
panel.Controls.Clear();
CreateListButtonHandler?.Invoke(this, e);
}
catch (Exception ex)
{
_ = new ErrorHandler(ex);
}
}
You seem to have a recursion here. GetHandlerData is added to the CreateListTextBoxHandler event (or delegate) and invokes CreateListTextBoxHandler again, which will call GetHandlerData again...?? But tbx_list_name.Text is passed to the model only once at the top level down to all the other calls.
You can fix this by passing a reference to the textbox instead of the text itself. Then you will always be able to retrieve the current text of the textbox.
public class ListCreationResponseModel
{
private readonly TextBox _listNameTextBox;
public ListCreationResponseModel(TextBox listNameTextBox)
{
_listNameTextBox = listNameTextBox;
}
public int Code { get; set; }
public string ListName => _listNameTextBox .Text;
}
Now, when you retrieve the ListName you don't get a stored value but the actual text of the textbox.
You can create the handler like this:
CreateListTextBoxHandler?.Invoke(this, new ListCreationResponseModel(tbx_list_name) {
Code = id
});

Can't display form inside TabPage in WinForms application

My WinForms application has form that contains several tabs. Inside each tab page i want to have another forms. That's how i add form to tab page:
public void InitializeTabs()
{
// Example #1
PlaceForm(FirstTabPage, new OneForm(EntryForm, Settings));
// Example #2
PlaceForm(SecondTabPage, new TwoForm(EntryForm, Settings));
}
Method PlaceForm
public void PlaceForm(TabPage tabPage, Form form)
{
form.TopLevel = false;
form.FormBorderStyle = FormBorderStyle.None;
form.Dock = DockStyle.Fill;
form.AutoScaleMode = AutoScaleMode.Dpi;
if (!tabPage.Controls.Contains(form))
{
tabPage.Controls.Add(form);
tabPage.Dock = DockStyle.Fill;
form.Show();
}
}
Example #1 - works - form added to tab page. But Example #2 - works strangly - if i add existing in project form class to second tab page - form is shown as expected, but when i create new form from wizard
and trying to display it on second tab page - form is not showing.
I finally confused, what i make wrong or where to search solution?

Form gets focused when I add a control

Im programatically adding controls to one of five panels in a form every 10 seconds. When all 5 panels are filled I clean the first one and add my new control in there and so on.
Now everytime I add a new control my form gets focused and the application I'm working is loses focus.
How can I prevent my form from beeing focused?
//EDIT
I found out that the last focused control (in my case a button) gets the focus upon the new created control, but I still dont know how to give my previous application the focus again
Code:
System.Threading.Timer timer = new System.Threading.Timer(x => {
if (!startStopBool) return;
if (controlIdx == 5) controlIdx = 0;
{
if (controlArray[controlIdx] != null)
{
DisposeControl(controlArray[controlIdx]);
}
controlArray[controlIdx] = AddControl(controlIdx);
controlIdx++;
}
}, null, 0, 10000);
after adding the control in the AddControl-function (a WebBrowser) the last used control from my form (the button) steals the focus

Rebind grid view in previous popup window from the current popup window using session ASP.net c#

I am working on a project in which I get a dataset and assign this to a session in the newly opened popup window. Now I need to rebind the grid view of the previous popup window using this updated session from the newly opened popup window. How can I implement this.
Details in Elaborate:
First Popup window (previous): model.htm inner binds attendee.aspx (in which grdAttendees exists)
New pop up: (display.aspx) genertated in button click from attendee.aspx
Referring to some samples i tried this but didn't work.
GridView grv = new GridView();
grv = ((GridView)this.Page.PreviousPage.FindControl("grdAttendees"));
grv.DataSource = "";
if (Session["map_hcp"] != null)
{
DataSet ds = (DataSet)Session["map_hcp"];
grv.DataSource = ds;
}
Any better idea to implement this?
you can use javscript for this
PARENT WINDOW:
function jsparentfunction()
{
alert('youve successfully calledme');
}
CHILD WINDOW
function executethischildjsfunction()
{
window.opener.jsparentfunction();
window.close();
}

Adding a twin tabPage to tabControl through a user command

I'm a newbie in c# and probably going to ask a very easy question, but I've not been able to find anything on the web to help.
I have a tabControl with a TabPage which is containing a TextBox object; this object, when the event "Text changed" is invoked, will perform the change of the parent tabPage's name.
The textbox where I typed "text changed by me" has a method which is managing changing the name of the tabPage:
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (this.textBox1.Text != "")
this.tabControl2.SelectedTab.Text = this.textBox1.Text;
else
this.tabControl2.SelectedTab.Text = "(no name)";
}
Into the current page menu is contained a control to add a new page, which runs this method when the user click on it:
private void addNewPageToolStripMenuItem_Click(object sender, EventArgs e)
{
int numPagine;
string strPagine;
numPagine = this.tabControl2.TabCount;
strPagine = numPagine.ToString();
this.tabControl2.TabPages.Add("new page" + strPagine);
}
...and here is the output, which is expected since I'm just asking to add a new empty tabPage:
So, my question is: how can I make possible that when the user is clicking on "Add new page", rather than creating an empty new tabPage the program is rather creating a page like the first one (i.e. containing a textbox into the same position which has a method to change the text of the parent tabPage that I have just created?
Here is an example.
//..
// create the new page
TabPage tpNew = new TabPage("new page..");
// add it to the tab
this.tabControl2.TabPages.Add(tpNew);
// create one labe with text and location like label1
Label lbl = new Label();
lbl.Text = label1.Text;
lbl.Location = label1.Location;
// create a new textbox..
TextBox tbx = new TextBox();
tbx.Location = textBox1.Location;
tpNew.Controls.Add(lbl);
tpNew.Controls.Add(tbx);
// add code to the new textbox via lambda code:
tbx.TextChanged += ( (sender2, evArgs) =>
{
if (tbx.Text != "")
this.tabControl2.SelectedTab.Text = tbx.Text;
else
this.tabControl2.SelectedTab.Text = "(no name)";
} );
For more complicated layout you may want to consider creating a user control..
You also may want to create the first page with this code; the, of course with real values for text and positions!
For creating a UserControl you go to the project tag and right click Add-UserControl-UserControl and name it, maybe myTagPageUC. Then you can do layout on it like on a form. A rather good example is right here on MSDN
The problem is that is has no connection to the form, meaning you'll have to code all sorts of references to make it work..
I'm not really sure if you may not be better off writing a complete clonePage method instead. It could work like the code above, but would loop over the Controls of the template page and check on the various types to add the right controls..
It really depends on what is more complicated: the Layout or the ties between the pages and the form and its other controls..

Categories