I have a form. I've added the strip down button using drag and drop in the form. How can I (in the program) create and fill the toolStripMenu Item? My menu could contain different element...with different names.
If you want to add items programmatically to a ToolStripDropDownButton just do:
var item1 = new ToolStripButton("my button");
toolStripDropDownButton1.DropDownItems.Add(item1);
var item2 = new ToolStripComboBox("my combo");
toolStripDropDownButton1.DropDownItems.Add(item2);
// etc ...
Instead, if you need to add other ToolStripDropDownButton or other elements directly to you menu (ToolStrip), just do:
var item1 = new ToolStripDropDownButton("my dropdown button");
toolStrip1.Items.Add(item1);
var item2 = new ToolStripProgressBar("my progress bar");
toolStrip1.Items.Add(item2);
// etc ...
EDIT:
You must do it after InitializeComponent() otherwise you won't be able to access to design-time added components, e.g.:
InitializeComponent();
// we're after InitializeComponent...
// let's add 10 buttons under "toolStripDropDownButton1" ...
for (int i = 0; i < 10; i++)
{
var item = new ToolStripButton("Button_"+i);
toolStripDropDownButton1.DropDownItems.Add(item);
}
For the DropDown property you need a ContextMenuStrip. The easiest way to find out how to fill it up is to drag&drop one from the toolbox onto your form, fill it up, select it in the DropDown property and afterwards take a look into the Designer.cs file to see how all the stuff is glued together.
The drawback of using the DropDownItems property is that you can't alter some properties like ShowImageMargin.
Related
I have two ContextMenuStrip(s) in a Windows Form Application, one of them has 3 items and the other one has none.
Let's suppose this:
ContextMenuStrip c1 = new ContextMenuStrip();
ContextMenuStrip c2;
c1 has 3 ToolStripMenuItems, c2 is the ContextMenuStrip destination where c1 items should be duplicated.
I tried to write this:
c2 = new ContextMenuStrip(c1.Container);
but it gives me an ArgumentNullException because c1.Container is Equal to null.
I cant figure out how to solve this, can you help me?
Ps.
I would new ToolStripMenuItem(s), no references
and
while or foreach loops solutions are not the best way to do this.
Thank you :)
Then, have a function that creates the ContextMenuStrip and call it each time a new menu is needed
Func<ContextMenuStrip> newContextMenuStrip = () => {
var c = new ContextMenuStrip();
c.Items.Add("item 1");
c.Items.Add("item 2");
c.Items.Add("item 3");
return c;
};
var c1 = newContextMenuStrip();
var c2 = newContextMenuStrip();
Late to the party, but I have had the same issue in the past and found a reasonably simple solution.
Say your toolStripMenuItem is declared as 'TSMI_open' in a context menu,
you can effectively hot-swap it between context menus as they open.
Something like this:
void Context1_Opening(object sender, CancelEventArgs e)
{
Context1.Items.Insert(0, TSMI_open);
}
void Context2_Opening(object sender, CancelEventArgs e)
{
Context2.Items.Insert(0, TSMI_open);
}
The menu item will appear on both menus when seamlessly, and will cause no errors if the same menu is opened twice consecutively.
You need to create a new ContextMenuStrip and add the Items (not the Container of c1 to the new menu:
c2 = new ContextMenuStrip();
c2.Items.AddRange(c1.Items);
But note that this does not duplicate the items. The same item instances are now in both menus.
If you want to clone them, this is rather complicated as you have to take care of the specific types of the items, the properties you want to clone and especially the event handlers.
A simple example could be:
c2.Items.AddRange(c1.Items.OfType<ToolStripItem>()
.Select(item => new ToolStripMenuItem(item.Text))
.OfType<ToolStripItem>().ToArray());
The second OfType is necessary to avoid a co-variant array conversion from ToolStripMenuItem[] to ToolStripItem[] which is expected by AddRange().
And a side note: Container is the component that contains the menu (thatswhy it's null when the menu is not shown) and not the thing the menu keeps its items in.
I am trying to find how I can add items to devExpress PopupMenu. I have tried the following:
manager = new BarManager();
listBoxMenu = new PopupMenu(manager);
listBoxMenu.ItemLinks.Add(manager.Items["Remove item"]);
listBoxMenu.ItemLinks.Add(manager.Items["Clear items"]);
As shown here http://documentation.devexpress.com/#WindowsForms/CustomDocument5472 (at the bottom), but it gives me an error saying the item is not initialized.
What is the proper way to add items? I can't find it anywhere.
Edit, here is how I did it:
//Creates the popup menu to be used for the keywords listbox
manager = new BarManager();
listBoxMenu = new PopupMenu(manager);
item = new BarButtonItem(manager, "Copy");
item2 = new BarButtonItem(manager, "Clear Item");
item3 = new BarButtonItem(manager, "Clear All Items");
listBoxMenu.ItemLinks.Add(item);
listBoxMenu.ItemLinks.Add(item2);
listBoxMenu.ItemLinks.Add(item3);
//Adds the seperator on the second item
item2.Links[0].BeginGroup = true;
manager.ItemClick += manager_ItemClick;
Check this code snippet and implement using the same way.
//create popup and manage objects
private DevExpress.XtraBars.BarManager barManager1;
private DevExpress.XtraBars.PopupMenu buttonContextMenu;
DevExpress.XtraBars.BarButtonItem menuButtonExport = new DevExpress.XtraBars.BarButtonItem();
DevExpress.XtraBars.BarButtonItem menuButtonSave = new DevExpress.XtraBars.BarButtonItem();
public TestForm8()
{
InitializeComponent();
barManager1 = new BarManager();
this.barManager1.Form = this;
buttonContextMenu = new DevExpress.XtraBars.PopupMenu(barManager1);
this.buttonContextMenu.Name = "subViewContextMenu";
menuButtonExport.Caption = "E&xport";
menuButtonExport.Id = 1;
menuButtonExport.Name = "menuButtonExport";
menuButtonExport.ItemClick += new ItemClickEventHandler(menuButtonExport_ItemClick);
menuButtonSave.Caption = "S&ave";
menuButtonSave.Id = 2;
menuButtonSave.Name = "menuButtonSave";
menuButtonSave.ItemClick += new ItemClickEventHandler(menuButtonSave_ItemClick);
//add items to barmanager
this.barManager1.Items.AddRange(new DevExpress.XtraBars.BarItem[] {
menuButtonExport,
menuButtonSave
});
//create links between bar items and popup
buttonContextMenu.ItemLinks.Add(barManager1.Items["menuButtonExport"]);
buttonContextMenu.ItemLinks.Add(barManager1.Items["menuButtonSave"]);
//finally set the context menu to the control or use the showpopup method on right click of control
barManager1.SetPopupContextMenu(btnInsert, buttonContextMenu);
}
Ref by step to include popup:
How to: Create a popup menu
How to: Add items to a container bar item (menu)
Populating Popup Menus
BarManager.SetPopupContextMenu Method
Your manager is empty:
manager = new BarManager();
The example you linked to is using a BarManager that was already created: barManager1, which I assume was created in the designer and populated with items.
From their BarManager help page:
After a BarManager has been added to a form/user control, you can create bars and bar commands using context menus right on the form, using the bar manager's Customization Window or its Designer. Please see the Toolbars Customization section, to learn more.
I'm looking for solution for my problem. I want to change location for tabcontrol's TabButtons or add control assigned to tabpage but outside TabControl. TabPages are added dynamically. Example:
Form1___________ _ [] X
_______________________
Some TabPage content
Tab1 | Tab2 | Tab3 | < >
TextBox assigned to Tab's
________________________
So if I change tabs by clicking on Tab1,Tab2,Tab3 TabPage + TextBox content should change depending on Tab. The first idea was to put TabButtons on bottom and add ArrayList what contains TextBox content, catch TabControl change tab event and change TextBox content, but there was an issue with editing and adding that content. In few words: I wan't to put TabButtons between 2 controls(for example between two textboxes).Do you have any ideas?
If I understand what you're asking for... You want when you click on a tab, it controls two different things? Like two different text boxes?
If that is true, you should be able to do it like this.
foreach (thing in your ArrayList)
{
TabPage tabPage = new TabPage("Name of tab"); // Add a new tab page
RichTextBox rtb = new System.Windows.Forms.RichTextBox();//RTF box
TextBox tb = new System.Windows.Forms.TextBox(); //Text box
//Set up size, position and properties
rtb.LoadFile("some/Path/to/a/file");
//set up size, position of properties
tb.Text = "Some text I want to display";
tabPage.Controls.Add(rtb); //Add both boxes to that tab
tabPage.Controls.Add(tb);
tabControl1.TabPages.Add(tabPage); //Add that page to the tab control
}
Only thing you should have to mess around with is the layout. And make sure to have the tabControl added with the designer.
you can create your own textbox class which inherits from textbox class :
class MyOwnTextBox:TextBox
{
public int parent_tab;
}
So you can add your textbox by assigning a parent_tab id to them . so in tab button click event , you can do something like that :
foreach(MyOwnTextBox txt in this.Controls)
{
if(txt.parent_tab==1) txt.visible=false;
}
You could also place the tabs on the left or the right side of your tab control. That is not perfect, but would come closer to your idea than placing them above or below the tab control.
You can add a new tab page dynamically like this
tabControl1.TabPages.Add("My new Tab");
I'm not sure I understand exactly what your trying to do. If you want to change the tab from another object, just use:
TabController.SelectTab(0);
If you want to remove a TabPage and add it to another, use:
TabController.Controls.Remove(TabPage1);
TabController2.Controls.Add(TabPage1);
Edit: From further read, I think you want something like this:
this.TabController.ControlAdded += AddLinksToBottomOfTabs;
public void mainSettingsTabController_ControlAdded(object sender, ControlEventArgs e)
{
//Create label with e.Control.Name as the title and
//add it to wherever you want it added.
}
I have a TabControl in a windows form. I have pragmaticly added new tabs like so:
for (int i = 1; i < numOfLanguages; i++)
{
// add a tab for each language
string tabTitle = split[i];
TabPage newTab = new TabPage(tabTitle);
languageTabs.TabPages.Add(newTab);
}
inside the loop I want to set up the other controlls for each tab. mainly I want to add buttons. I have seen this code:
tabPage1.Controls.Add(new Button());
Based off this example I want to do something similar like:
languageTabs.SelectTab(split[i]).Add(new Button());
I know that this code wont work. Have been looking through the params and cant see anything that lets me do this kind of thing.
Any ideas community?
SelectTab moves the actual TabControl to the specified tab, it does not return the tab to let you manipulate it.
You can index into the tab pages as follows:
languageTabs.TabPages[2].Controls.Add(new Button());
If you have set the Name property on the TabPage on creation, then you can also find individual tabs by key:
for (int i = 1; i < numOfLanguages; i++)
{
// add a tab for each language
string tabTitle = split[i];
TabPage newTab = new TabPage(tabTitle);
newTab.Name = tabTitle;
languageTabs.TabPages.Add(newTab);
}
...
languageTabs.TabPages[split[i]].Controls.Add(new Button());
(See MSDN for more)
Whichever is most convenient.
LINQ?
languageTabs.TabPages.First(tab => tab.Title == split[i]).Add(new Button());
This might be not reliable (crash) if your tabcontrol does not have tab with specific name, so you might want more reliable way:
if (languageTabs.TabPages.Exists(tab => tab.Title == split[i]))
{
languageTabs.TabPages.First(tab => tab.Title == split[i]).Add(new Button());
}
I want to create a kind of 4 x 3 matrix with textboxes and checkboxes. Whether the element is checkbox or textbox depends upon the values in database.I want it to be dynamic. What is the best way to start?
// something like this but I need to fill in each elements of the matrix...
private void CreateSpecificControl(string requestedType)
{
if (requestedType == "CheckBox")
{
CheckBox control1 = new CheckBox();
control1.Click += new EventHandler(chk_CheckedChanged);
//TableLayout panel
layout.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 25));
layout.Controls.Add(control1);
}
else
{
Label control1 = new Label();
control1.Text = "Not a checkbox";
layout.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 25));
layout.Controls.Add(control1);
}
}
Use a usercontrol. See this tutorial.
At run time you can change the contents of the User control. There's a Controls collection in each user control that you can add or remove elements from. For example if you want to add check boxes just do somethign like this:
myUserControl.Controls.Add(new CheckBox());
Similarly elements can be removed from this collection, thus achieving a dynamic behaviour.