I have a form in which I would like to be able to add tabs dynamically through the use of a button (much like the buttons most modern browsers have for adding tabs). These tabs should also contain a text box which is stretched to the individual tab's width and height upon creation.
I apologise for the lack of code but besides instantiating a TabControl container within a Form class, I have no clue as to what I should do next.
Thanks in advance.
All you need is to call the Add method on the TabControl.TabPages collection, then add other controls to that TabPage, like so:
private void button1_Click(object sender, EventArgs e)
{
TabPage tp = new TabPage("Test");
tabControl1.TabPages.Add(tp);
TextBox tb = new TextBox();
tb.Dock = DockStyle.Fill;
tb.Multiline = true;
tp.Controls.Add(tb);
}
Hope this helps
Related
I'm having a difficult time trying to work with tooltips.
I'm trying to add a tooltip with different text to each dynamically created tab in a tabcontrol.
It's important to note that this tab is created from a form that contains a docked form where the tabcontrol is in.
This is, a main Form with a docking area, in where I have docked a results form, which contains an - initially empty - tabcontrol.
When you start the application this results form doesnt exists, I also create it dynamically whenever the user press certains parts of the main form, each one created as a new tab in the results form tabcontrol.
This is how I generate the tabs:
generateResultForm();
TabPage newtp = new TabPage("Nuevo paciente")
_result.TabControl.TabPages.Add(newtp);
newtp.Name = setTabName("np");
Now, I've tried putting a tooltip in the results form, then tried to first generate the tooltip by adding below something like _result.ResultsTooltip.SetToolTip(newtp, "Creación de un nuevo paciente.");, which didn't work. Then, since once the tab is created, it becomes selected, I tried to add it in the results class by something like WorkareaTooltip.SetToolTip(tabControl.SelectedTab, "Cosas"); in the selectedindexchange event from the tabcontrol.
I don't think it would have been a great solution, but I don't know what else to try.
Of course the tabcontrol has its ShowToolTips property set to true.
If anyone could help me that'll be great.
Thanks for reading, and sorry if there are any language mistakes :)
//EDITED
This is the code i'm actually using (and doesn't work)
TabPage newtp = new TabPage("Nuevo paciente");
_workareaform.TabControl.TabPages.Add(newtp);
newtp.Name = "np";
var tooltip = new ToolTip();
tooltip.SetToolTip(newtp, "Creación de un nuevo paciente.");
Now, it doesn't work, might be because of the whole configuration.
Just to be clear, this tab is in a TabControl which is in a Form docked into a dockContainer in another Form.
Here is an image if it.
http://i.imgur.com/fVz6e06.png
As you can see, no tooltip at all.
Have you tried setting ToolTipText property as shown below?. It worked for me.
_result.TabControl.ShowToolTips = true;
TabPage newtp = new TabPage("Nuevo paciente");
_result.TabControl.TabPages.Add(newtp);
newtp.ToolTipText = "this is tooltip";
If you're working with another form you need to reference the other form TabControl
In this sample I create a Form1 instance (with TabControl in it) from my Form2 and then add page and tooltip.
private void Form2_Load(object sender, EventArgs e)
{
//instantiate another form
var f1 = new Form1();
//find tabcontrol on new form
var tc = (TabControl) f1.Controls["tabControl1"];
//create page
TabPage newtp = new TabPage("Nuevo paciente");
newtp.Name = "Paciente1";
tc.TabPages.Add(newtp);
//add tooltip
var tt1 = new ToolTip();
tt1.SetToolTip(newtp, "paciente 1 tooltip");
//show other form
f1.Show();
}
Here is my form
If I click on "Add" on the first panel I want to create "Strategy1_2" just below the first and shift all others panels down.
If I click again I want to create Strategy1_3 (...)
I know how to create a button but not how to duplicate a entire panel.
Here is my code for a button is it far from this procedure ?
private void addstrat1_i_Click(object sender, EventArgs e)
{
panel3strat.Width += 200;
Button addstrat1_2 = new Button();
addstrat3_2.Size = new Size(210, 41);
addstrat1_2.Location = new Point(31,89);
addstrat1_2.Visible = true;
panel1strat.Controls.Add(addstrat3_2);
}
The best way would be that you create a UserControl for your strategy panel. You can then insert the UserControls to a FlowLayoutPanel. This will resolve your issue with placing controls exactly and to create a copy of some panels.
Be aware that you can run out of resources (e.g. windows handles) when adding to much controls on your form. This can be solved by only showing a certain amount of controls and shifting the data through this "fixed" controls while scrolling.
I recommend having two methods: CreatePanelBlock() that will issue a UserControl that you'll add to your container, and BindPanelWithData(...) that will setup the dependencies.
Remember, you may make your panel as a custom control.
I have a windows form and i dont want to make any other windows forms just one windows form and different user controls how can i change between user controls for example hide one and show the other user control programmatically ?
private void Btt_info_Click(object sender, EventArgs e)
{
Frm_Main frm_main = new Frm_Main();
frm_main.Controls["panel1"].Controls.Clear();
UC_Info uc_info = new UC_Info();
frm_main.Controls["panel1"].Controls.Add(uc_info);
}
i added this but it doesnt work
Add a container control (if I remember correctly, there's a containers section in the toolbox?), like a panel. Create usercontrols for what you want to dynamically switch around. So make like a 'HomePage' usercontrol and a 'LoginPage' usercontrol. Dynamically add the usercontrol that you want to display to the container. WHen you want, remove it from the container and add a different usercontrol:
Panel myPanel = new Panel();
LoginPage ctlLoginPage = new LoginPage();
HomePage ctlHomePage = new HomePage();
//add the loginpage to the panel first
myPanel.Controls.Add(ctlLoginPage);
...do stuff...
//remove whatever control is currently in the Panel
myPanel.Controls.Clear();
//add the other control, the HomePage control instead now
myPanel.Controls.Add(ctlHomePage);
..do other stuff...
I usually do it this way so you leave your form itself open to add common controls and stuff that might be shared between your different 'pages'.
EDIT: Note that I normally would add the panel in the designer and not create it dynamically in the code. This was just an example.
EDIT: The interaction between your mainform and usercontrols can be handled in a few different ways, and I am not saying that any of these is the correct method.
You create a static property for your Panel on the Mainform, so that
you can always access it to swap your controls around.
In this example I'll also add a static method for it
enum PanelControlsEnum {HomePage, LoginPage};
public static Panel MyContainerPanel {get;set;}
public static void SwitchPanelControls(PanelControlsEnum selControl){
..put your switch panels code here..
}
Then inside your usercontrol you call a predefined method, something like:
MainForm.SwitchPanelControls(PanelControlsEnum.HomePage);
Another method is to bind the button click event on your mainform
instead of inside the form.
Like This:
HomePage ctlHomePage = new HomePage();
ctlHomePage.Click += MyClickEvent;
myPanel.Controls.Add(ctlHomePage)
...
private void MyClickEvent(object sender, RoutedEventArgs e)
{
..switch user control code here...
}
Create a method that returns a UserControl object. Then put conditions in that method as to which control you want to load at a specific condition and then in your main form code.
UserControl control = GetControlFromMyMethod();
form1.Controls.Add(control);
where 'control' is the returned control from your method.
To remove the existing one you have to loop through the form1.Controls and find out the control and call 'Remove'.
Update:
Mike C has a better idea of adding a panel and loading your desired control on the panel as then it's easy to remove your control and you then don't have to loop through the forms controls to find it and then remove it.
Try this:
this.Controls.Clear();
usercontrol load = new usercontrol ();
this.Controls.Add(load);
load.Show();
you could try this it will definitely help you as it did helped me a lot it short and straight to the point hope that will help
I searched the internet for this but i couldn't find how to do it with C#
What i am trying to do is make it so that when i click on my NewTab button, a new tab appears with the same controls that were on the first tab. I saw some information on how to add a UserControl to your form, but C# doesn't have anything like that.
And for everyone who would say "Post your code", i don't have any, so don't bother saying that, the only code i have is the code for the program and that wouldn't help anyone.
EDIT
I have rewritten my solution to use reflection.
using System.Reflection;
// your TabControl will be defined in your designer
TabControl tc;
// as will your original TabPage
TabPage tpOld = tc.SelectedTab;
TabPage tpNew = new TabPage();
foreach(Control c in tpOld.Controls)
{
Control cNew = (Control) Activator.CreateInstance(c.GetType());
PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(c);
foreach (PropertyDescriptor entry in pdc)
{
object val = entry.GetValue(c);
entry.SetValue(cNew, val);
}
// add control to new TabPage
tpNew.Controls.Add(cNew);
}
tc.TabPages.Add(tpNew);
Some information can be found here.
http://www.codeproject.com/Articles/12976/How-to-Clone-Serialize-Copy-Paste-a-Windows-Forms
Your best bet would be to look at this article:
Code Project
Then apply the following code to add the cloned control (this would be in your button click handler code (based on article):
private void button1_Click(object sender, EventArgs e)
{
// create new tab
TabPage tp = new TabPage();
// iterate through each control and clone it
foreach (Control c in this.tabControl1.TabPages[0].Controls)
{
// clone control (this references the code project download ControlFactory.cs)
Control ctrl = CtrlCloneTst.ControlFactory.CloneCtrl(c);
// now add it to the new tab
tp.Controls.Add(ctrl);
// set bounds to size and position
ctrl.SetBounds(c.Bounds.X, c.Bounds.Y, c.Bounds.Width, c.Bounds.Height);
}
// now add tab page
this.tabControl1.TabPages.Add(tp);
}
Then you would need to hook the event handlers up. Will have to think about this.
I know it's an old thread but I just figured out a way for myself and thought I should share it. It's really simple and tested in .Net 4.6.
Please note that this solution does not actually create new controls, just re-assigns them all to new TabPage, so you have to use AddRange each time you change tabs. New tab will show the exact same controls, content and values included.
// Create an array and copy controls from first tab to it.
Array tabLayout = new Control [numberOfControls];
YourTabControl.TabPages[0].Controls.CopyTo(tabLayout, 0);
// AddRange each time you change a tab.
YourTabControl.TabPages[newTabIndex].Controls.AddRange((Control[])tabLayout);
I have a tabcontrol with 3 tabpages. I need to add a left margin to the first tabpage ( so move all tabpages move right of 200px ). How can I do it??
Using Visual Studio 2008 / c#
EDIT Reading again I think you're more looking for the controls on each page to be on the right of the tabs rather than moving the buttons.
As Hans suggests a panel would be the easiest way. But it's not pretty.
private void Form1_Load(object sender, EventArgs e)
{
// Create spacer tab with a name long enough to reach the 200px mark
TabPage spacer = new TabPage("..............................................................");
tabControl1.TabPages.Insert(0, spacer);
// Create a panel at the same location of the tab control.
Panel spacerBlock = new Panel();
spacerBlock.Name = "spacer";
spacerBlock.Location = tabControl1.Location;
spacerBlock.Width = 198;
spacerBlock.Height = 20;
this.Controls.Add(spacerBlock);
spacerBlock.BringToFront();
}
private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
{
// Ensure the user can't use the keyboard to somehow select the spacer tab.
if (tabControl1.SelectedIndex == 0)
tabControl1.SelectedIndex = 1;
// Check if the second (first I guess) tab is selected and adjust the panel to keep the look consistant.
if (tabControl1.SelectedIndex == 1)
this.Controls["spacer"].Width = 198;
else
this.Controls["spacer"].Width = 200;
}
You'll want to make sure the tab isn't selectable by the user via keyboard shortcuts thus the index change check.
Also note the panel will have to have its width adjusted if the second (first in your case) tab is selected due to the 3d GUI effect.
Honestly the hassle of taking into account the appearance settings of the end user to ensure the spacer tab's text and the panel width are correct length doesn't really make up for fancy look IMHO.
Only other option I could think of would be a tab panel with a 16px height. Again this would have to be adjusted depending on the end users appearance settings, not to mention the excess overhead in getting it all working.
If it's the AjaxControlToolkit tab control, add this CSS class:
.TabContainer .ajax__tab_header
{
padding-left: 200px;
}
you would need a work-around for that because tab pages can't be moved. You might wanna place a groupbox inside the tabpage and then you can add all the controls inside the groupbox as you desire...
// tabPage 1
this.tabPage1.Controls.Add(this.groupBox1);
// groupBox1
this.groupBox1.Location = new System.Drawing.Point(200,6);
this.groupBox1.Controls.Add(this.textBox1);
this.groupBox1.Controls.Add(this.AnyControls); //etc