I have a WinForms project based heavily on the DevExpress Windows Forms suite. I am working on a control that appears as below:
I use the term programme to differentiate between training programmes for people, from program, meaning computer program. In the image there are 3 ProgrammeGroup user controls. Each has a header, with 2 combos, and below that, a ProgrammeDetail user control with programme details.
When the top, left combo shows a value of Yes or blank, the programme details must be visible, otherwise not. When making a ProgrammeDetail control invisible, I also set its Height to zero, and the outer ProgrammeGroup control shrinks on auto-size.
However, if I set the Yes/No combo on the middle ProgrammeGroup to No, that
ProgrammeGroup shrinks, but leaves a gap between the header only middle control and the bottom control. This gap is visible in the following image:
How can I lay my ProgrammeGroup controls out so that if one shrinks in height, all those below it are moved up, meaning no empty gap. I am hoping that one of the many different panels in the DevExpress WinForms suite can help me do this, but I am stumped at finding one.
Solution to this problem is using FlowLayoutPanel which automatically align controls inside it next to each other.
The best way to adjust sizes and locations of child controls is to place them onto LayoutControl. This control is specially designed for such tasks. To hide unnecessary layout items/groups, use the BaseLayoutItem.Visibility property.
I should also note that LayoutControl is flexible and supports different modes including the Flow Layout Mode.
See Also:
Customization Form
Related
I have a ToolStripContainer with a MenuStrip and a ToolStrip inside, both at the top. They're arranged as usual on Windows with the menu bar above the toolbar. Now, Windows Forms and DPI scaling support has always been a bit iffy. While everything looks fine at 100 %, I'm currently using 110 % DPI scaling and the menu bar and toolbar switch positions in the ToolStripContainer (I'd suspect it's the same with higher scaling factors, though):
My guess as to why this happens is that the designer places both controls at specific locations, even though they are arranged by the container, and with DPI scaling the ToolStripContainer gets locations for its children that would be consistent with placing the toolbar above the menu bar, as if someone dragged the bars around and reordered them (which is possible interactively, after all).
Short of replacing the MenuStrip with a MainMenu, is there a simple(ish) way of ensuring that regardless of DPI scaling the order of both remains consistent? I've got about 50 different windows to change in pretty much the same manner and would also rather avoid putting extra code into the codebehind file¹.
Things I've tried so far:
All changes in the designer have been applied at 100 % scale.
Change the z-order of the toolbar and menu bar in an attempt to control their order. This works with panels and docking, but doesn't apply to ToolStripContainer, apparently.
Docking the MenuStrip at the top. Doesn't work; the designer just removes Dock = None from the code and displays Top as the default value, but with scaling applied, it's back to Dock = None in the designer (and even without touching the Form in the designer, the result at runtime is the same).
¹ These are demo applications for a control library and the main point here is to keep the code clean and still providing a good experience out of the box. So a designer-only solution where the code is hidden away in already-awful code that no one reads would be preferable.
They are very frustrating components to work with. Because they can be dragged and moved it looks like the Location is the key, even though they behave a bit like they're docked. In OnLoad or OnShown have you simply tried resetting the desired location?
menuStrip.Location = new Point();
toolStrip.Location = new Point(0, toolStrip.Height);
The Visual Studio WinForms designer lets you snap together text boxes, list boxes, buttons, and so forth reasonably well. However, a check box with CheckAlign=MiddleRight does not work quite like the others, because it has two components: the built-in label, and the check box itself. If you line up the text with other labels, the check box is left floating and will not automatically line up. You can turn off AutoSize and attempt to size the CheckBox control so the check box lines up, but this is touchy and will be thrown off by custom font sizes.
In this example, I've almost lined up the check box with the other controls, but not quite:
If I had several check boxes it would be a real headache, as with AutoSize turned off the position of the check box is relative to the end of the text, so each control has to be individually sized pixel by pixel.
What's the best way to line up check boxes with other controls?
One workaround is to not include text with the CheckBox and instead have a separate Label control. However, by doing so you lose the ability to click on the label to toggle the check box. On a high-resolution screen, clicking a 10x10 pixel is finicky, a poor UX experience. You could add an OnClick event to the label, of course, but that seems like solving the wrong problem.
Here's an example of someone else with the same issue: in the preferences panel in Oracle SQL Developer, when there's a mix of properties the check boxes are handled with separate labels and boxes:
Personally, i avoid that issue by not having the CheckBoxes aligned to the right:
rather than having the caption on the left.
I'm sort-of just nit picking here, but maybe there's a simple solution which will save me some time.
When I'm drawing my Winforms GUI in the designer, controls snap to certain points. I can align the baseline of the text of one control to that of another, I can align the left and/or top of one control to another, etc. This is all great.
What's great too, is that the controls snap to other controls spaced with their margins. This means that if I'm making a vertical array of TextBoxes, then I can have them equidistant in my GUI - it looks less messy.
However not everything snaps correctly, or at all. Say I have put in my TextBoxes and now I wish to reduce the width of my form so that there is no white space between the edges of the TextBoxes and the edge of the form. Additionally, I want the distance between the edge of the TextBoxes and the edge of the Form to be the same on the left as it is on the right. If I drag the right edge of the form to the left, towards the TextBoxes it will not snap. I'm left with either calculations to work out what the width should be, or a juggling act to gradually reduce the width until the TextBox is snapping to both the left of the right.
I'm not saying this process is particularly difficult or time consuming. It's just that if it were to snap, the whole process would be infinitely easier.
Is there a built-in option in VS2010, or perhaps an extension? Or maybe I'm just doing it wrong in the first place?
The snap lines in the designer work perfectly when moving or resizing any of the built-in controls. The only time that they don't work is when you are resizing the form itself.
I agree that it would be extremely convenient to have snap lines here, as well. I wish I knew of a way to enable this. But unfortunately, I don't believe that there is one.
The workarounds are either to calculate the proper size mathematically, or guess at resizing the form then check your work by dragging one of the controls (and using the snap lines that appear). I go through the same "juggling act" that you describe on an unfortunately regular basis.
Whenever a control needs to be positioned so that it "snaps" to a form edge I usually move (or resize) the controls to the correct size first, and then change the controls "Anchor" property of those controls to be anchored to the corresponding form edge (even if the form itself won't be allowed to resize).
That way whenever I resize the form, the controls position relative to that form remains the same, simply resizing or moving the control as required (depending on the Anchor property chosen).
I completely agree that the ability to "snap" the form to controls when resizing the form would be extremely useful, but its normally possible to work-around using the anchor property in this way - the times when its doesn't work (such as when a form consists entirely of a column of text-boxes is a fixed height), I'm afraid you need to resort to calculations, but I find that most of my dialogs are resizable.
Given a WPF Application running full screen, a fair amount of controls some of which will animate from off screen to center. I was wondering if there are any special ways to save on the amount of time required to optimize an application for different screen resolutions?
For example, using Blend I've setup some text, which is originally off screen to scroll into view. Now in design mode the start positions are static. If resolution changes the start positions will obviously not be correct.
So I guess to correct this, during app startup. I need to
Check resolution
Move the text box to the desired start location
Adjust the storyboard as required, so the frames all have correct co-ordinates depending on the res of the screen.
I don't mind doing all of this, but if there is an easier way please share!
Thanks
In WPF layout of controls should be made in such way, that when size of window or content changes, controls automaticaly resize/reposition themselves to reflect this change.
This is highly affected how your layout is made, especialy by using specific panels, that do layout of their child elements.
This is also made obvious by using device-independent units for sizes, margins and sometimes positions of controls. And also allows different kind of zooming and scaling of whole UI without any need to redesign the whole thing.
If you are trying to position your controls absolutely, either by using Canvas panel or margins, your are doing it totaly wrong.
In WPF, scene is measured in abstract units, not pixels, and controls are freely scaled. There should be no problems to center something, or what?
How should I develop a form that can resize nicely?
While that sounds like a simple question the problem I'm struggling with is the fact I'm reproducing an existing application I made in Swing several years back. Its built around a single form that hides/reveals panels as you select different options.
Its around 600 x 700 pixels wide say but its a fixed size window.
Is this good practice? The GUI works fine this way but if you look at other applications you can resize them easily. Granted some applications look stupid full size but should the option be there?
The main screen consists of about five buttons, when maximized this looks ridicilous, but at the same time if the form is resizable the moment you start resizing the form it becomes stupid.
I'm aware of layout managers and so forth so no need to tell me to check these out, my main problem is the fact I can produce an excellent fixed width application but that's about it.
Any advice/links for this?
Personally, I think fixed size forms are a horrible User Experience.
I always try to build mine so that they can be gracefully resized (even if they do look a little odd).
If you're using .NET for your WinForms development, you can easily use a table layout and then anchor your controls so that they resize politely.
A fixed size gui is generally a bad idea because most forms have a user interface element that can sensibly be resized.
First consider a form that only contains two buttons. (A silly form, yeah, but for the sake of discussion we'll assume that it's the right thing for the job) When sized initially in the right way (appropriately for localization, e.g.), there's no good reason to make the form resizable. If you enlarged or mazimized the form, you'd only make the area to click the button bigger, but you'd be clicking a smaller area than the button to resize it, so there's no reason. In this case, it doesn't make sense for the form to be resizable because there's no user-benefit for adding the extra control.
Now consider a form that contains a listview. There are clear usability benefits to making this form resizable in both dimensions. The listview may contain more items than can be shown in a smaller area, both horizontally and vertically, so it makes sense that this form be fully resizable to allow the user to display as much or as little of the data as they want.
Every form control implicitly has certain degrees of freedom either by constraint or by convention. Conventionally, buttons don't resize, so they have no degrees of freedom (even though they can resize). Listviews and listboxes have two degrees of freedom, horizontal to display more data per row and vertical to display more rows. Single line textboxes have one degree of freedom, horizontal. Because they're single line, they don't expand vertically, but they do expand horizontally.
These degrees of freedom help you determine the layout of your form. Form elements that have degrees of freedom should resize in the appropriate direction when the form is resized. I prefer to design my forms with only one control that has two degrees of freedom in an area where areas are typically separated via splitters. I prefer to avoid the explicit table layout panel unless there's a very specific need for it because it's easy to make a form overly complex when there's a table layout to work with. The anchors in WinForms provide an extremely powerful and flexible abstraction for control layout, however, so I strongly encourage their usage.
Aside from the layout panels (my favorite is the table layout), become familiar with the Anchor, Dock (more for the table layout), and MinimumSize properties. They do a lot of work for you when it comes to resizing forms.
Most of your forms will look goofy maximized but my general rules were these:
Buttons stay the same size
regardless of form size (no Top and
Bottom anchor; no Left and Right
anchor).
Buttons stay in the same place with
respect to a border (Anchor
combinations: {Left, Top}, {Left,
Bottom}, {Right, Top}, {Right,
Bottom})
Only the right-most textbox grows
when resizing (Anchor = Left and
Right).
Single multiline textboxes rule the form
(Anchor = Left, Right, Top, Bottom)
With multiple multiline textboxes, the lowest one rules the form.
MinimumSize is less that 640x480 whenever possible; 800x600 max.
The default size is the MinimumSize -- let the users make it bigger if they need to.