I currently am working on a WinForm project in which there are several different tabs. Within each tab there are various controls such as buttons, sub-tabs, text-boxes, ect...
I need to consolidate the overall application which involves taking certain controls from one tab and moving them to another. When I first tried doing so, I simply copy and pasted the controls. As you can imagine this didn't work due to the fact that I didn't move the properties with the controls, I really just created NEW ones on a different tab. Therefore when I complied the code, nothing worked because there was no code assigned to the new controls.
When I tried it again, this time I CUT and paste which also maintains the same properties as the old controls (specifically the reference name in the code), so as far as I can tell, the code should identify the controls by name, and apply the same actions. However, when I compile the code, the application successfully builds but the controls do not perform any actions.
At this point I am not sure what to do...
Use the Document Outline.
View... Other Windows... Document Outline.
Select the required component and drag it from one tab page to the other in the tree control. I did this and the actions are preserved in the new tab page.
Drag the item out of the tab control and onto the form itself. Change to the other tab. Then drag the item into that tab. It is essentially 2 drag moves, but since you do not ever cut, all code linking is maintained. If your tab control takes up the entire form, simply make it smaller while you do the preceding steps and then make it large again when you are done.
When you "cut" the controls, you sever the connections between the controls and their respective events. When you "paste" them again, they're not hooked up to the events anymore, so they don't appear to do anything.
The "event" methods should still be present in your code, but you'll have to manually go through and subscribe each event to each control again (via the Properties window).
Alternatively, revert those changes, then open the .Designer.cs file and look for something like this:
this.tabPage1.Controls.Add(this.dataGridView1);
Which (for example) places dataGridView1 inside tabPage1.
If you wanted to move the DataGridView to another TabPage, you could just change this.tabPage1 in the above code to this.tabPage2.
this.tabPage2.Controls.Add(this.dataGridView1);
Then you can flip back over to the designer view and move the control around to wherever you want it within the TabPage.
I just tested it. What is happening when you cut and paste your controls, you losing the wiring of the events. What you need to do after cut and paste is to go to control properties-events, find the event in question and on the right, select a method that you want to handle that event.
This will cut them from the first TabPage and paste them on the second, i think you can do this as often as you want. And with a small change you can make it a truly copy.
hope it helps
private void ControlsToTabPage(TabPage from, TabPage to)
{
Control[] ctrlArray = new Control[from.Controls.Count];
from.Controls.CopyTo(ctrlArray, 0);
to.Controls.AddRange(ctrlArray);
}
Related
I am using Windows Forms.
I do only have one Frame. In this Frame I organized some Controls together. Where the Controls in one Row belong together (they form an Object). And overall I have five of those Rows, with the same Controls.
Eg.: Name , Surname, Age, Income, etc (in one Row)
There are Dropdownlists, Checkboxes, NumicUpDown, etc
I would now need to know an way to "bind" them together. The same counts for the Events. Because at the moment I would make for every different Control an Event and then distuingish them by an Number at the end of the Controls Name, which would be rather annoying. And then generate from that the Object.
What way do I have to not make dozens of Events and indicate that everything in one Row belongs together?
For grouping them together on the Form (not Frame) - put them all on one Panel.
To use the same even handler for all of them - simply subscribe to the same one. (Using the designer - select the events, and choose from the drop down. For doing this from code - just do YourControl2.EventName += YourControl1.EventName.) Note that this is not possible for every type of Control and every event. It's only possible if the events have the same signature.
You can easily create a UserControl. Right-click the project or a folder in the project and select UserControl. You can then add controls to it, in the designer, just as for Forms.
Once you have compiled the project, your UserControl will appear at the top of the toolbox and you can drag and drop it onto a form.
Like this would would create a user control representing one row, and add one of them for each row to your form. You can also add additional properties, methods and events to your user control class. They will automatically appear in the properties window.
But in your case, a DataRepeater Control for Windows Forms would be appropriate. It is part of the Visual Basic Power Packs, but just works as well in C# projects.
take all your controlls in one Panel. So You can with group more RadioButtons and they can know one for anderer. Then you can between them scwiching so you becomming what you whant.
EDIT: I needed to skip control creation during post back -- see my answer below.
I'm working on a very basic front end to a simple tool and I wanted to present some data in a much more sorted and useful way, instead of making one huge wall of text. I found this tutorial on building a simple tabbed interface using MultiView, but have run into a bizarre problem. I can't use Ajax tabs because of legal hissy fits over 3rd party software.
My webpage is a basic ASP.NET page with a user control plopped in the middle of it. In this control's ascx file, I defined the Menu (empty) and the MultiView (also empty) so that I can dynamically populate the tabs with content driven from an external file.
When the default page's OnInitComplete function is called, I call through to the user control to load the data file, then build out the tabs and the view content based on the loaded data. I tried doing this from PageLoad, PreInit, and CreateChildControls, but I kept getting an errors saying that I was setting the the MultiView's active view index at an invalid time (and also that there were 0 views despite the fact I just added a bunch of them):
ActiveViewIndex is being set to '0'. It must be smaller than the
current number of View controls '0'. For dynamically added views, make
sure they are added before or in Page_PreInit event.
But OnInitComplete appears to work just fine, so I went with that.
I iterate over the loaded data (multiple lists of strings), and for each list, I add a MenuItem with the list's title to the Menu and a View to the MultiView. The View is populated with a table->row->cell as in the above tutorial. In the cell, I add the list title and a CheckBoxList data bound to the list of strings.
So far so good, but when I click on a tab (or one of the checkboxes, etc) and there is a postback or something like that (the screen flashes as the site redraws itself), there is now a duplicate set of MenuItems immediately after the original. Each time I click on a tab or checkbox, another set of menu items are added.
I clear the MenuItem's Items list prior to building the controls and I verify that the controls hierarchy is structurally as expected after the control construction. Yet when one of my callbacks is called, my MenuItem list magically has some items added to it. None of my other controls appear affected at all. As a hack, I can remove the duplicates manually in my menu's OnMenuItemClick event, but I'd have to do the same in any of the callbacks I receive. Obviously I'd rather prevent this from happening. This has me stumped and I haven't been able to find anything online about it. Why would one set of controls have some content duplicated, yet every other control maintain its state correctly? My code is really simple so there isn't a way to add additional menu items without also adding the views. Anyway, there are a correct number of items prior to clicking on the tab/checkbox, an additional set immediately following in the callback.
This is my first time using ASP.NET, so I'm learning as I go. :) Thanks!
My problem was that I was not testing for postback before creating the controls. The code below is working for me.
In my user control's code behind:
protected void OnInitComplete( EventArgs e )
{
if( !Page.IsPostBack )
{
CreateMyControls();
}
}
I have created a Windows form using a Tab Control, but it has a header with it. I want to hide it. I am not able to do it using any properties of the Tab Control. Is there any property defined for hiding the tab header for the Tab Control without going through the code?
Use following code to hide the tabs or set these properties in design.
tabControl.Appearance = TabAppearance.FlatButtons;
tabControl.ItemSize = new Size(0, 1);
tabControl.SizeMode = TabSizeMode.Fixed;
You want the tab panels without the feature allowing a user to switch between them, so I suppose you want to create few separate sets of controls to be shown to the user one at a time. You can achieve this in several ways (you can choose one of them if you find it appropriate in your case):
Use several Panel controls instead of several tabs in the TabControl, however, it would be hard to work in the designer, because all the controls would be visible
Use different Forms instead of tabs to keep the layout parts separated. It can be ok, but you may not want to use multiple Forms, so it depends on a specific case.
and finally, the suggested solution:
Encapsulate each set of controls in a UserControl. This allows you to keep each layout separately, so you can easily design each of them without the other controls getting in the way ;). The the code handling each of the layouts would also be separated. Then just drag those controls in the Form and use set their visibilities appropriately to show the one you want.
If none of those suggestions work for you, let me know, so I can look for other possible solutions.
It's more easy as you think, you just drag the panel's window upper, so will be outside of the form.
Use DrawMode: OwnerDrawFixed will hide TabPage header text DrawMode : OwnerDrawFixed
Another way to achieve the same (or similar) is: You can remove tabs from TabControl.TabPages collection and then add the tab you want to show.
During the Form initialization I remove tabs (so into the designer I can easily manage them) and in some control event (as button click) I show the tab the user has to see.
Something like that:
// During form load:
ctrTab.TabPages.Clear();
// ......
// During button click or some other event:
if(rbSend.Checked)
ctrTab.TabPages.Add(pgSend);
else
ctrTab.TabPages.Add(pgReceive);
In this way the user can still see the header tab but just as title of controls group, he can't change/switch the current active tab.
C# WinForms:
I am designing my form and I have a couple of TableLauots. so I design my first tablelayout, throw it on the panel and set Dock->Top ... then I design my second one and do the same and set Dock->Top, it goes to Top again and good, it places under the previous one that was on top...I design the third one and set its dock.top and good it is under second one which is under first one...but I dunno what is the diffrence for the forth one that when I set its dock.top, it changes the order of the other three ones and get places some where in between them, it does not get placed under the third one...any idea what should I look in to?
It depends on the order you have added those controls to their container. The earlier added control will be the topper one and so on ...
To fix it, "Cut" the forth control and "Paste" it again to the container and it will take the desirable place.
Another way to fix it is by modifying the designer file code to re-order the adding of those controls to their container.
Right click on the Controls and select "Send to Back" or "Bring to Front", or use the Document Outline Window to rearrange the Z-Order of the items. Document Outline helps a lot when creating WinForms things with lots of controls.
The dock layout is based on the order they are added to the container.
I usually go to the *.Designer.cs file and modify the InitializeComponent() method to manually re-order how the controls are added to the container.
this.Controls.Add(this.panel1);
this.Controls.Add(this.panel4);
this.Controls.Add(this.panel3);
this.Controls.Add(this.panel2);
This order is opposite on display
You have to organize the order of your controls in the Document Outline window (VIEW -> Other Windows -> Document Outline (Ctrl+W, U)). Select your form in Desing Mode and you will see all your components in a tree view. Use the arrows on the top to select the desired order.
It is better than cut and past because it will avoid loss of binding callbacks.
You can change the ordering of a control to move to a particular index
containerPanel.Controls.SetChildIndex(Control, n); //sets control to be the Nth element from the bottom
I have a form with a bunch of panels, and some panels inside groupboxes. When using the TabOrder tool in Vs2005, the controls outside of containers are given integers (0), the controls inside panels are given decimals (72.0), and the controls within panels within groupboxes are given three-part values (73.73.0). Unfortunately the resulting tab order has nothing to do with the order I clicked my controls.
Does this tool simply not support nested containers? Am I doing something wrong? Perhaps holding Shift- or Ctrl- when I click (I've tried these with no success)?
Am I going to be forced to manually type in three-part tab orders for all my controls? That would be a bummer.
The tab order tool is not designed for you to enter values manually; it is designed for you to click on controls in the order that you'd like them to progress as the user tabs.
The numbers are not decimals; they represent the tab order of the control within its parent container. For example, if you have a Form with a Panel named panel1 and a Button inside of it named button1, then button1 would display a number like:
X.Y
X is the tab order of panel1
Y is the tab order of button1 within panel1.
I will acknowledge that the designer isn't as intuitive (or transparent) as it probably should be, but it does work.
I had the same problem with textboxes and buttons within group box in VS2010. TabOrder tool was just useless: Tab orders were broken no matter how I re-ordered the tab stops. In order to make the correct tab order I had to re-order of how controls are added to the group box in form designer initialization code:
this.groupBox2.Controls.Add(this.startTimeTextBox);
this.groupBox2.Controls.Add(this.endTimeTextBox);
this.groupBox2.Controls.Add(this.exitButton);
This way tab order would be startTimeTextBox -> endTimeTextBox -> exitButton and so on.
I think I figured out the way to do it in the designer: the trick is apparently that you have to click the panels/groupboxes as well in order to assign the different parts of the full ordering; in this way, it seems that a bredth-first clicking method needs to be used as opposed to clicking the child controls themselves.
Kinda sad, since it forces you to know the full structure of the whole form instead of just what the user sees.
I had this same problem and discovered this tool: http://archive.msdn.microsoft.com/cdstabindex
I had to change the manifest to make it work with VS2010 though. Also, I've modified the source code for myself to make the UI a little better, but even as it is, I would recommend having a look at this tool.
Remove Group-boxes from Controls and try again this works for me :)