I have a base form with two buttons (e.g. OK and Cancel). I want to use a TableLayoutPanel and have the two buttons in it. Child forms should be able to add more controls to the table as well as modify its layout itself via the designer.
So far I can't get this to work. I have tried the following:
Adding the TableLayoutPanel to the child form. Designer refuses to add the two buttons to the panel.
Adding the TableLayoutPanel in the base form. Can't add controls to the panel from the child form.
In the base form you have to set the property Modifiers = Protected for the TableLayoutPanel and any other control you want to change in the child forms.
The reason why you cant edit your TableLayoutPanel in the derived class is because you are attempting to use a feature of WinForms called 'visual inheritance'. Unfortunately, the TableLayoutPanel does not support visual inheritance:
http://msdn.microsoft.com/en-us/library/ms171689.aspx (read at the bottom of the page)
http://msdn.microsoft.com/en-us/library/1z3efhd2.aspx
This is why it appears blocked in the inherited controls. I am not sure why they do not support this feature, but I have recently come across the same problem and ended up having to solve the problem another way.
Since this hasn't received an answer since almost over a year and WindowsForms is slowly losing against WPF, the answer seems to be "just don't do it".
Related
Problem:
I cannot add any controls to a groupbox, if the controls were declared in another form.
Background Information:
I have MainForm which inherits from Form. It provides some functionality which I need in all of my forms, and have also added some custom controls/images which I need in all of the other forms.
With my forms, I reposition the controls/images from the MainForm to wherever I need and all is well.
But for some reason, I cannot move these same controls/images into existing GroupBoxes.
When I say can't I mean that VS is not letting me; when I drag the control over the groupbox, my mouse cursor switches to this "error" sign:
If I understand correctly then you have two or more level of inheritance hierarchy with your form, base class have the GroupBox you're trying to modify it in designer via derived form. Am I correct?
In that case VS prevents you to move control to groupbox which is declared in base class?
If yes, There are couple of things to check.
Check whether your groupbox is atleast protected, so that you can access it in derived class.
If yes, While you're dragging the control just right click the mouse(holding left button), then drop it into groupbox. It should work.
If you have troubles yet make the groupbox as protected internal and give a try.
Hope this helps
This question already has an answer here:
How to enable design support in a custom control?
(1 answer)
Closed 8 years ago.
New to Visual Studio 2010, but have been doing Windows development using other platforms for over 10 years. I've done the following in other platforms such as Visual FoxPro, but it doesn't seem to work in VS...
I created a User Control consisting of a panel that contains a few labels and a couple of buttons. When I make a new form (WinForm) and drop this User Control onto the form, I cannot add additional controls to the panel. The User Control appears in the document outline as a single item (purple gear icon) without access to the panel or the controls contained in the panel.
Is this an inappropriate use of a User Control? In this application, I will have many panels with the same buttons and labels in them along with unique combinations of other controls. It seemed natural to make a User Control that provided the panel and contained controls that are common, then just drop in the controls that are unique to the various instances of the panel in the designer. If I have to build all of the panels in the designer from the base controls, I will, but I was hoping to use what seemed to be an obvious OOP process.
If you inherit not from UserControl but from Panel your control remains a Panel and you can add child controls on it.
Cautions :
1) Child controls added by the control itself are considered as child controls by many Panel methods and getters (they aren't automatically hidden). I never tried this. But subclassing Form and derivating user forms from subclassed forms works fine. And the WinForms Designer gracefully display inherited childs as unmodifiable elements.
2) In Panel derivated class prefer to override OnXxx() method to do internal actions on Panel events than attaching handler to Xxx events: This will allow you to decide if your code should be executed before or after attached handlers by placing it before or after the call to base.OnXxx(sender, e);
Though the User Control itself that you are creating my contain a Panel, its technically not a Panel anymore in your application. It is technically a new control.
Maybe you should build a dynamic enough control where all the panels, and controls are on the same custom user control but dynamically show and hide them as needed.
I have a form full of controls, and there is no room for other controls. On the bottom of the form I have a panel with some controls on it.
My goal is that when a certain button is clicked, the original panel on the bottom will be replaced with another panel that contains controls which could be created before the program starts, meaning these controls in the panel do not need to be created dynamically. The replace action would be executed by setting each panel's visible field to it's matched value.
I have thought of two ways of doing this - either creating the new panel (and it's controls) dynamically and adding it to the form instead of the original, or creating the new panel in another form and when the relevant button is clicked the panel being taken from that form and added to the required form (by creating an instance of the new form and making it's panel's modifier public). The "side form"'s purpose is only to create that panel, it has no functionality of it's own.
The advantages of creating the new panel dynamically:
There is no need to create a zero-functionality form.
The advantages of creating the new panel in a side form:
It's very clear which controls are added to the new panel and their positions.
It's very easy to set the location and other fields of the controls in the new panel.
Which way is better?
Thanks!
Have you considered TabControl? That seems a good fit for your needs. Other controls I can think of are StackPanel (Can be fairly easily done for Windows Forms) or OutlookBar like control (again a user control).
Simplest and quickest way seems to be TabControl.
Edit:
SideForm is a different windows form I suppose. So if you are thinking to make controls public and then change their visibility etc, please don't. Use delegates to handle SideForm's events in MainForm.
As you mentioned, there is no room for more controls, I would suggest more screens rather than just one. Having said that I do not know much about your current UI design and functionality so it's up to you.
I would say having the controls hidden and just playing with the Visibility is fine. This means that you do not have to worry about positioning of controls, anchoring and docking at runtime. The problem could well be loading of form. Having huge number of controls having a lot of data associated with them may slow things down.
IMO the best way would be to utilise user controls for this purpose. Simply create one user control per panel you wish to show/hide and place your controls inside. This way you will have both: the designer and the "extra form" you wanted.
I'm building a C# WinForms program, and my textboxes do not allow the user to highlight the text consistently throughout the program.
In some places, the highlighting works normally: you type something in the box, click and drag over some text, and it highlights where you dragged.
In other places, clicking and dragging does not select the text. The only way to do it is by double clicking on the text.
I haven't changed any default properties of these textboxes or messed with any event listeners. I placed brand new textboxes in different places, and they behave differently.
I'm wondering if it has something to do with the properties of the Form the TextBox is contained in, since it seems to appear that either all textboxes in a particular form work, or none do. However, as far as I can tell the properties look to be the same across the board, and I don't ever remember changing anything.
To me it seems like it's happening randomly. I can't find any information on the topic. Does anybody have any idea what I'm talking about?
EDIT: Ok, I figured out where the problem lies, but I still don't know how to fix it.
It happens only in forms which have been added to a SplitContainer in my main window like so:
myForm.TopLevel = false;
this.splitContainer.Panel2.Controls.Add(myForm);
myForm.Show();
EDIT 2: I now know that this is the same issue encountered here: Windows Forms: Unable to Click to Focus a MaskedTextBox in a Non TopLevel Form . The accepted answer isn't useful to me, and the other answers seem impractical, since I'd have to add event handlers to every single textbox...
I had the same problem today. I tried changing TopLevel as others have suggested. This didn't work. Somewhere along my search I saw a suggestion to create a click event for the text box and use it to force focus on the control. This made no difference either. There were no events that should intercept and block a click event. It was just an MDI child with a few controls on it stuffed inside a panel on a split container. I couldn't highlight text in textboxes or textbox-derived controls though.
Turns out the solution was to switch the order of childform.Show() and panel.Controls.Add(childform). If you add the child form before it is shown, you apparently cause this bug.
I'm a little perplexed at what you're trying to accomplish. I'm used to using a user control if I want to embed something on a SplitPanel, and using an MDI form if I want child forms.
Do either of these approaches work for you, and if not, can you explain why not/what you are trying to accomplish?
Thanks!
James
* Edit *
You can add a panel (regular panel, not a split panel) to an MDI parent form and dock it to the left. Add whatever you currently have in the left panel of the SplitContainer to this left-docked panel, instead. Now you can instantiate forms, set them as children to the main MDI parent, and have all the window functionality you're looking for... You can maximize them, and they will fill the right-side of the MDI parent; you can pick cascade or tile from the window menu, etc.
If you want to let the user dynamically resize the left panel, drop a splitter panel into the right-hand portion of the main MDI form container; it will dock left by default, and show up to the immediate right of the panel. Now when you run, you can drag the border of the panel to resize.
Remember, an MDI form is like any other form... you can add any control you want to its surface, and .NET is pretty smart about how it incorporates the child windows.
If you're still not sure of what I'm trying to describe, I'll try to find somewhere I can drop a sample project... because everything is really done in the designer, there's not really any code I can show you. Here's the code for creating a form as an MDI child (running from within the MDI parent):
MyForm frm = new MyForm();
frm.MdiParent = this;
frm.Show();
That's all there is to it.
HTH!
James
I have inherited a control from Panel-Class.
I have added some events to this control. I gave move - ability to this control
and so on ..
I have two display screens. I have a main program where the inherited
panel is displaying an image on a small area. I want to show this panel
fullscreen on a second.
I created a new form and use the same control... But i can not move both screens
together. What should I do ?
If you want to be able to manipulate both forms at the same time, show the second form with Show() instead of ShowDialog(). You can certainly pass the original panel to the second form and add it to the form's Controls collection. I am not sure if this is the best way to do it (sharing one control across two forms), but I don't know your requirements either.
I wouldn't use a second form, but a second 'mode' (fullscreen vs. not) on your existing form.
You can have 2 panel controls, or just one and resize.
I think this kind of behaviour calls for a model-view pattern. If that's implemented, the rest should fall into place.
The problem is that you only have one instance of your inherited panel. You actually have to make another "copy" of it, a new instance, before you can add it to the other form.
Mypanel mypanel1 = new Mypanel();
Mypanel mypanel1copy = new Mypanel();
You can either edit these instances to contain the same data all the time through the run, or use something like "Deep Copy":
How do you do a deep copy of an object in .NET (C# specifically)?
Keep in mind, that any changes to mypanel1 should be done to mypanel1copy, too.