I am working on an ERP project. it is a button on treeView box and when it is clicking on a button in treeView it must create a Tab with its content (content which is defined-designed before).
I can add a tab programically but how can I design its content?
Adding this to your click event of your treeview should do what you are after:
var contentControl = new ContentControl (); //This is what we will put all your content in
contentControl.Dock = DockStyle.Fill;
var page = new TabPage("Tab Text"); //the title of your new tab
page.Controls.Add(contentControl); //add the content to the tab
TabControl1.TabPages.Add(page); //add the tab to the tabControl
To your project, add a new UserControl called ContentControl (or whatever you need, just using this in my example), and fill it with all the contents you want to appear in your tab.
You have few solutions, the simplest one is to create TabPage, create desired Controls, set up their properties (i.e. Size, Location, Text etc.), add them to the TabPage and then add TabPage to the TabControl.
TabPage tp = new TabPage();
//create controls and set their properties
Button btn1 = new Button();
btn1.Location = new Point(10,10);
btn1.Size = new System.Drawing.Size(30,15);
//add control to the TabPage
tp.Controls.Add(btn1);
//add TabPage to the TabControl
tabControl1.TabPages.Add(tp);
the second solution is to override TabPage in your class, for instance CustomTabPage where you will set up controls in the constructor of the class. Then, when you want to add new TabPage, create your CustomTabPage instance and add it to the TabControl.
public class CustomTabPage : TabPage
{
public CustomTabPage()
{
//create your Controls and setup their properties
Button btn1 = new Button();
btn1.Location = new Point(20, 20);
btn1.Size = new System.Drawing.Size(40, 20);
//add controls to the CustomTabPage
this.Controls.Add(btn1);
}
}
//Create CustomTabPage
CustomTabPage ctp = new CustomTabPage();
tabControl1.TabPages.Add(ctp);
the third solution (the best but the most complicated) is to create your desired UserControl with everything you want on it (you can use Designer help), then create an instance of your UserControl, Create a TabPage and add UserControl on the TabPage. Then add TabPage to the TabControl.
public partial class CustomControlForTabPage : UserControl
{
public CustomControlForTabPage()
{
InitializeComponent();
}
}
//Create CustomControl
TabPage tp = new TabPage();
CustomControlForTabPage ccftp = new CustomControlForTabPage();
//set properties you like for your custom control
tp.Controls.Add(ccftp);
tabControl1.TabPages.Add(ctp);
Add a new user control to the project then use the designer to do controls/layout, then when you click all you do is add a new instance of the user control to the tab - probably docked to fill the tab unless your form's size is fixed.
Related
I'm trying to create a dynamic flowcontrolPanel and make it visible after adding controls to it. However the problem now is, the controls are added successfully but the panel is not visible on the screen. The below piece of code is a sample which I have tried form my side:
List<object> lstChild = lstFromChild;
//creating an instance for the flowlayoutpanel
FlowLayoutPanel objflowParent = new FlowLayoutPanel();
objflowParent.Name = "flowLayoutParent";
objflowParent.Location = new Point(380,155);
objflowParent.Size = new Size(800, 800);
objflowParent.BackColor = Color.DarkCyan;
objflowParent.BorderStyle = BorderStyle.Fixed3D;
objflowParent.Dock = DockStyle.Fill;
objflowParent.AutoSizeMode = AutoSizeMode.GrowAndShrink;
objflowParent.Size = new Size(300, 30);
objflowParent.SuspendLayout();
//Adding Controls to the flowlayoutpanel
foreach (Control item in lstChild)
{
objflowParent.Controls.Add(item);
}
objflowParent.ResumeLayout(false);
//Tried to hide a datagrid available in the screen to check if it is hiding the panel
dgMainGrid.Hide();
this.Show();
Note: lstChild is the list carried form another form with controls loaded in it.
How do I create a simple form that has a MenuStrip at the top and a TabControl filling all of the remaining space?
If I go with DockStyle.Top/DockStyke.Fill tabControl fills whole form regardless of MenuStrip:
public MainWindow()
{
initializeComponent();
}
private void initializeComponent()
{
MenuStrip mainMenu = new MenuStrip();
mainMenu.Dock = DockStyle.Top;
TabControl tabs = new TabControl();
tabs.Dock = DockStyle.Fill;
TabPage test = new TabPage("test");
tabs.Controls.Add(test);
Controls.Add(mainMenu);
Controls.Add(tabs);
}
You should change the z-order of mainMenu or tabs. For example you can call:
mainMenu.SendToBack();
//Or
//tabs.BringToFront();
After adding controls to the controls collection.
Another approach through designer, without writing code manually, so your changes will affect design time too
Use Document outline tab and arrange control's hierarchy with your requirements
View -> Other Windows -> Document outline or CTRL+ALT+T
I have a custom Tabs Control I created. It works as a coloured Label for the tab itself and as a Panel to hold the contents. My application reads UI parameters from config files. Take this line as an example from the controls config:
RTFBOX=(ID - rtf1) (BOUNDS - 0,0,100,100) (MULTILINE - enable) (FILE - email_rules.rtf)
This line tells the application to create an instance of my custom RichTextBoxPlus class and the important thing to take from this is that it is set up to read rich text from the FILE parameter. If I don't add this RichTextBoxPlus to another Control it shows it's rich text formatting absolutely fine.
I have another config that reads actions at runtime, this can be simple stuff like telling a Button created with the controls config that when it is clicked, it should fire off an email using content from a TextBox control. I have an action that pairs controls to each tab in the Tabs custom control. For example:
ADDTOTABS=(OBJECT - tabsControl1) (CONTROLS - panel1, panel2)
This finds tabsControl1 and adds panel1 to the 1st tab and panel2 to the 2nd tab. In this example, Panels are being added to each tab instead of individual controls as the Panels could hold multiple controls, handled at runtime through the ADDTOPANEL action.
ADDTOPANEL=(OBJECT - rtf1) (TARGET - panel1) (TRIGGER - onload)
So the rtf1 instance of RichTextBoxPlus is added to panel1 which is then added to the respective Panel of the Tabs control's 1st tab.
What I have found is rtf1 displays with rich text formatting absolutely fine if added to panel1 but not adding panel1 to Tabs.
The ADDTOTABS action executes this method:
private void TabContents_Action(Tabs tabpanel, string[] ctrls)
{
string[] tabs = tabpanel.GetTabNames();
for(int i = 0; i < tabs.Length; i++)
{
Control control = this.Controls.Find(ctrls[i], true).FirstOrDefault();
tabpanel.SetTaggedObject(control, tabs[i]);
}
tabpanel.SetTabActive(tabs[0]);
}
The SetTaggedObject method of the Tabs class finds the Panel control that corresponds with the tab name provided:
public void SetTaggedObject(Control ctrl, string tab)
{
Control container = this.Controls.Find(tab, false).FirstOrDefault();
container.Controls.Add(ctrl);
}
Doesn't seem to be anything untoward about this method.
The SetTabActive method of the Tabs class has a little more bulk. This handles changing the appearance of all tabs so that inactive tabs look different to the active tab. It is also hides and shows the panels for each tab based on whether the tab is active.
public void SetTabActive(string tab)
{
LabelPlus activeTab = this.tabs.Find(x => x.Name.Equals(tab));
List<LabelPlus> inactiveTabs = new List<LabelPlus>(this.tabs.FindAll(x => !x.Name.Equals(tab)));
activeTab.BackColor = this.ActiveColor;
activeTab.ForeColor = this.ActiveForeColor;
string panelName = tab.Remove(tab.Length - this.tabSuffix.Length);
Panel activeTabPanel = (Panel)this.Controls.Find(panelName, true).FirstOrDefault();
activeTabPanel.Bounds = new Rectangle(
new Point(this.tabStart, this.originalLocation.Y + this.TabTotalHeight), this.Size);
ControlCollection activeTabCtrls = activeTabPanel.Controls;
foreach(LabelPlus inactiveTab in inactiveTabs)
{
inactiveTab.BackColor = this.InactiveColor;
inactiveTab.ForeColor = this.InactiveForeColor;
string inactivePanelName = inactiveTab.Name.Remove(inactiveTab.Name.Length - this.tabSuffix.Length);
Panel inactiveTabPanel = (Panel)this.Controls.Find(inactivePanelName, true).FirstOrDefault();//
inactiveTabPanel.Bounds = new Rectangle(
new Point(this.tabStart, this.originalLocation.Y + this.TabTotalHeight), this.Size);
ControlCollection inactiveTabControls = inactiveTabPanel.Controls
foreach (Control ctrl in inactiveTabControls) { ctrl.Location = new Point(0, ctrl.Location.Y); ctrl.Hide(); }
}
foreach (Control ctrl in activeTabCtrls)
{ ctrl.Location = new Point(0, ctrl.Location.Y); ctrl.Show(); }
}
Not sure but I'd say the issue must be in this method. Any thoughts?
I'm having a MainWindow which is a NavigationWindow. Inside this MainWindow I want to switch in several Pages. One of the Pages has to be dynamically generated by Code, not by XAML. When I had a normal window before, I could add UI components like this:
Button b = new Button();
b.Content = "Hello";
this.AddChild(b);
Or if I added (for example) a StackPanel with this method first, I could add Children to this StackPanel with:
myPanel.Children.Add(b);
However, the Page Class doesn't have a Children Attribute or a AddChild Method.
The only method I found so far is:
AddVisualChild(b);
The page shows but I don't see any components which I added with this method.
So how do I add Children to a WPF-Page correctly?
First of all, the Window.AddChild will throw an exception when you add more than one object to it, because Window is a ContentControl. Page allowes only 1 child .So you set the child using the Page.Content property. So you want to add a container to your Page and then add children to the container.
For example:
Button b = new Button();
b.Content = "Hello";
StackPanel myPanel = new StackPanel();
myPanel.Children.Add(b);
this.Content = myPanel;
I'm not really sure if this works for you but you could try to set the content of a page to a user control. E.g. use a StackPanel and add all the children to it. After that you set the content of the Page to the Stackpanel.
Here is an lazy example in the constructor of a MainWindow.
public MainWindow()
{
InitializeComponent();
StackPanel panel = new StackPanel();
Button b1 = new Button {Content = "Hello"};
Button b2 = new Button {Content = "Hi"};
panel.Children.Add(b1);
panel.Children.Add(b2);
Page page = new Page {Content = panel};
this.Content = page;
}
I've a tabcontrol on my page with 2 tabs. Now I want to create another tabcontrol dynamically and want to add the existing tab control to dynamically created tab control tabs.
Is is possible? I'm not able to add this.
Here is my code:
TabControl tbdynamic = new TabControl();
TabPage tbpaagedynamic = new TabPage();
tbpaagedynamic.Controls.Add(statictabcontrol);
tbdynamic.TabPages.Add(tbpaagedynamic);
Any idea?
Yes, it is posiible.
Add dynamic tab to Form :
this.Controls.Add(tbdynamic);
example
TabControl tbdynamic = new TabControl();
tbdynamic.Height = 200;
tbdynamic.Width = 200;
TabPage mPage = new TabPage();
mPage.Text = "Test Page";
tbdynamic.TabPages.Add(mPage);
mPage.Controls.Add(statictabcontrol);
statictabcontrol.Top = 0;
statictabcontrol.Left = 0;
this.Controls.Add(tbdynamic);
Just add the bringToFrontMethod() at the end of adding it to your Window.
tbdynamic.BringToFRont();