I am creating many usercontrols in an windows application in C# 3.5. I want to copy any usercontrol and paste it on another location of the MDIForm. Similarly in case of Cut option. I am using these three options in a contextmenustrip. And theses options are visible when I right click on the usercontrol. Can anyone tell me how It will be done at run time?
That requires giving the controls a new Parent. Explicitly supported by Winforms, they can even have no parent, quite a trick. You can do it directly by assigning the Parent property. Or by adding the control to another Controls collection, it will be automatically removed from the one it was in before.
Be careful, this flexibility comes with a price. It is also a source of a nasty leak that can crash your program after a while. That's caused by the no-parent trick, otherwise triggered by a Cut without a subsequent Paste. If you use Controls.Remove() or Controls.Clear() then the control is moved to the 'parking window', an invisible window created by the Winforms plumbing that acts as a temporary host. If you then don't either move the control to another parent or forget to call its Dispose() method then the control will live forever. Until your program runs out of resources or the user terminates the program.
The out of resources bomb ("cannot create window") typically happens after a few hours so is easily missed when debugging. You can see it in TaskMgr.exe, Processes tab. View + Select Columns and tick USER objects. Also tick GDI Objects and Handles to feel good about your program not leaking.
If you put the controls on a Panel then you can move them all together with just a single line of code by moving the panel.
You could remove the control from the ControlCollection in case of cut and cache it to add that control to some other form when pasted like you could do
panel1.Controls.Add(newPanelButton);// To add, you might have to change the control `Location` as per your need
panel1.Controls.Remove(newPanelButton);//To remove
In case of having cut/copy effect on the same form you could just change the Location of the control to the new location where you want to paste that control.
Related
I'm on Windows 10, maintaining a C# Desktop application using Visual Studio 2019, putting controls onto a Form (System.Windows.Forms.Form). I'm attempting to change an application; reworking where the controls go etc., so there is code and control design that I want to keep and put into different locations. I am using the visual designer and connecting to code using the control events (as opposed to creating the forms dynamically).
I have Document Outline visible on the left; I cut several groups of controls I intend to paste back later, so all that one particular TableLayoutPanel has in it now is two buttons. But I cannot find those buttons in the designer. I can see them in the Document Outline; they're in a TableLayoutPanel (in a group box in another TableLayoutPanel on a TabPage, etc.). When I click on a control in the Document Outline, the corresponding control is usually highlighted in the View; however, when I click on either of these buttons, nothing is highlighted in the view.
I tried resizing the Form (which determines the sizes of all these panels/tableLayoutPanels set to 'fill'); it's currently at 1367,850; one of the button locations shows as 664,752, but I don't know in what coordinate system that applies. I tried manually setting the location to 50,50 in the properties window, but it won't let me change that there.
These buttons appear at the bottom of the form; they've never appeared there, but I've noticed sometimes the designer has shown dotted-line outlines of them outside the form entirely. They appear in place when the application is run.
I've tried changing between the 100% scaling and the 125% scaling; that didn't help. For two buttons, I suppose I could delete them and recreate them, but there are many, many controls on this UI, and if there's some trick to making things appear I'd like to know about it.
Is there a trick to this that I'm missing?
I've inherited a project that has been modified in a way that is beyond me to undo. Every single control on the form is not modifiable in the designer except through the Properties window and each control has an icon in the area below (see image) in the section usually reserved for non-visible items (e.g. DataSource). How do I undo this and return the designer to a usable version without wiping it all out and starting over?
Could the controls be locked? I have run into legacy code in which the programmers have locked every single control, meaning you cannot move or resize them in the designer. If so, select them all and change the Locked property to false (you should also see a padlock in the designer when you select them, if they are locked.
If not, well maybe you can create a new dialog/form and copy the controls unto it and see if that clears things up. Another trick could be to add a second instance of the user control(s) to see if the newly added control works as expected. If so, go through the code and point all events/logic to the new control (tedious yes, but may work).
Also, you can never edit individual sub-controls of a user control in the designer for the form/control where you instantiated the user control. You must go to the designer of the user control to edit individual (sub)controls of a user control.
If the Infragistics controls are shown in the Component Tray, than there might be version differences. What you could try is to open the licenses.licx file and remove the content from there. Do you have an Infragistics controls installed on your machine? Are there any difference after setting the "Specific Version" property of the Infragistics assemblies to "false"?
Is this happening only in your existing project or the same behavior is reproducible in a new project as well?
You have to load the dll that contains the controls you can't modify in the designer.
the steps are:
right click in the ToolBox in visual studio designer (on General for example).
select Choose Items...
after a while vs load items press browse and select the dll
interested than the componet should appear in the grid. Do this for
all the dll that contains the controls you are interested.
-Make sure you have checked the component (use filter text box if you
have a lot of component loaded).
press ok.
Now you should be able to move controls in designer.
I have also seen behavior this when a user control or form is incorrectly flagged as a 'Component'.
Some manual hacking of the .csproj file may be the answer then. Open the project file in a text editor, and find the references to your control. If you find a subtype defined as:
<Compile Include="MyControl.cs">
<SubType>Component</SubType>
</Compile>
The forms designer will interpret it as such. You can change the 'SubType' to 'UserControl' to fix it.
I have a form that contains a lot of runtime generated controls (image, button, panel,...), about 100 controls (I'm making a card matching game so there is a lot of controls in the form).
I place the generating code into the constructor and each time the app starts, it took about 3-5s to load all the controls completely.
If I bring another window on top and then back to my app, the controls will be redrawn again.
How can I prevent the controls from being redrawn? If you don't mind, please give me a simple example in C#.
Any help is appreciated!
I found this article that explains how to do this in .NET by calling the WIN API SET_MESSAGE function to set the WM_SETREDRAW flag for the control you do not want updated. Although you can stop certain controls from updating, are you sure you can't approach this issue by reducing the number of controls on the page? 100 Controls seems like a lot and may be an indication that you need to have multiple views.
Enjoy!
My suggestion is to use the form as a drawing surface and draw your card bitmaps directly onto the form. Its not hard to do.
You can add a handler to the form Paint event which will give you parameters with a Graphics object. Use graphics.DrawImageUnscaled to draw each card at the location you want.
This will make the app much much faster.
Preventing a control from redrawing is fairly pointless. You'll get a hole where a control was supposed to appear, your user won't have any use for that hole.
It redraws slowly simply because you have too many controls. You can only get it to redraw faster by using less controls. Or by using controls that can display multiple items in one window, like ListBox, ListView, TreeView, DataGridView.
Note that your specific issue is fixed in Vista and Windows 7. The Aero theme uses off-screen buffering for windows. Which means that windows don't need to repaint themselves anymore when they are obscured by another window. You will however still get slow redraws when the user minimizes the window and restores it.
You might want to consider using a single data table control. A ListView (or something like ObjectListView) may be a good option.
If your data isn't really a list/table, you should split the controls into separate tab pages, which would improve both performance and usability.
i have a winforms application. i have a user control with a lot of icons. the user can load this control on a form many times (in a tabbed layout). right now i am loading the icons each time the control is created (could be up to 50 times in teh app). is there any way to cache these icons in the application. if i did this, would that decrease the number of gdi handles that i am using as this is becoming an issue.
You can make a singleton class for each icon. The first reference it creates the handle. Subsequent calls uses the existing handle.
Without knowing more about your user control my next suggestion can be only be very general. But you could have a single bitmap layer on which you draw all your icons. The remaining elements of your user control would exists above and around this bitmap.
Unfortunately this idea may be problematic performance wise. Require you to refactor the code you all ready use for arranging icons. Finally it is non-institutive from how frameworks with a control-form structure ideally works.
We ran into a resource problem with entry forms for the parameteric shape we ship with our CAM software. Too many text entries caused various forms of strangeness and leaks. So we instead created labels with borders that looked like text entries and had ONE text entry (and a combo box entry too). When the user tabs, enters, or clicked the single text entry moved to the new entry and the label was setup for the previous entry.
This is totally a non-intuitive setup than how you would normally code this but it was the only way to deal with our resource problem.
In my experience it seems that GUI Frameworks have issues when you have to deal with dozens or hundreds of entries and that you have to approach the problem using a different design.
If the issue is the number of "icons" (not sure what you mean here) you can use Image-Lists. For example, a Listview control can reference icons in an image-list, instead of keeping a full copy for each item (not sure if this applies to your case though).
I'm writing an application that is basically just a preferences dialog, much like the tree-view preferences dialog that Visual Studio itself uses. The function of the application is simply a pass-through for data from a serial device to a file. It performs many, many transformations on the data before writing it to the file, so the GUI for the application is simply all the settings that dictate what those transformations should be.
What's the best way to go about designing/coding a tree-view preferences dialog? The way I've been going about it is building the main window with a docked tree control on the left. Then I have been creating container controls that correspond to each node of the tree. When a node is selected, the app brings that node's corresponding container control to the front, moves it to the right position, and maximizes it in the main window. This seems really, really clunky while designing it. It basically means I have tons of container controls beyond the edge of the main window during design time that I have to keep scrolling the main window over to in order to work with them. I don't know if this totally makes sense the way I'm writing this, but maybe this visual for what I'm talking about will make more sense:
Basically I have to work with this huge form, with container controls all over the place, and then do a bunch of run-time reformatting to make it all work. This seems like a lot of extra work. Am I doing this in a totally stupid way? Is there some "obvious" easier way of doing this that I'm missing?
A tidier way is to create separate forms for each 'pane' and, in each form constructor, set
this.TopLevel = false;
this.FormBorderStyle = FormBorderStyle.None;
this.Dock = DockStyle.Fill;
That way, each of these forms can be laid out in its own designer, instantiated one or more times at runtime, and added to the empty area like a normal control.
Perhaps the main form could use a SplitContainer with a static TreeView in one panel, and space to add these forms in the other. Once they are added, they could be flipped through using Hide/Show or BringToFront/SendToBack methods.
SeparateForm f = new SeparateForm();
MainFormSplitContainer.Panel2.Controls.Add(f);
f.Show();
Greg Hurlman wrote:
Why not just show/hide the proper container when a node is selected in the grid? Have the containers all sized appropriately in the same spot, and hide all but the default, which would be preselected in the grid on load.
Unfortunately, that's what I'm trying to avoid. I'm looking for an easy way to handle the interface during design time, with minimal reformatting code needed to get it working during run time.
I like Duncan's answer because it means the design of each node's interface can be kept completely separate. This means I don't get overlap on the snapping guidelines and other design time advantages.
I would probably create several panel classes based on a base class inheriting CustomControl. These controls would then have methods like Save/Load and stuff like that. If so I can design each of these panels separately.
I have used a Wizard control that in design mode, handled several pages, so that one could click next in the designer and design all the pages at once through the designer. Though this had several disadvantages when connecting code to the controls, it probably means that you could have a similar setup by building some designer classes. I have never myself written any designer classes in VS, so I can't say how to or if its worth it :-)
I'm a little curious of how you intend to handle the load/save of values to/from the controls? There must be a lot of code in one class if all your pages are in one big Form?
And yet another way would of course be to generate the gui code as each page is requested, using info about what type of settings there are.