Show and Hide UserControls (BringToFront/SendToBack) - c#

I'm working on a "tricky" UI. Part of what I need to do is easily show and hide various UserControls. Generally one control will occupy the entire main window when needed, the other's will hide.
In WinForms I used to simply use SendToBack and BringToFront and easily showed the control I wanted to show. Now I have no clue. Played around with zorder but that didn't seem to work.
I'm thinking maybe put all the controls I want on the main window, then pro-grammatically resize them and remove the unused ones... or something.
Any ideas?

You should set the Visibility property to Collapsed, Hidden or Visbible depending on whether you want the controls removed, hidden or shown.
As #AresAvatar points out Collapsed removes the control completely so it takes up no space, this means that other controls may move around the container. If the position of elements is important then using Hidden will be the better option.
UIElement.Visibility Property on MSDN
Visibility Enumeration on MSDN

Related

How to initially place WPF controls on dynamic fullscreen application

Alright, so I'm trying to figure out the best way to accomplish this for my rather unique case. I have a fullscreen WPF application where controls are added to a Grid dynamically and the user is given the option to freely move/resize them. The controls can be individually moved or resized anywhere on the parent Grid but I have prevented them from overlapping via their MouseMove events. They also cannot be moved outside of their container. Since the app will be running on machines with different monitor sizes, I need to take that into consideration when making the original layout. I have an initial layout that I would like to use, but it would seem that I'm out of options:
I first tried using rows and columns just to (initially) place the controls that are added. This method places them correctly but becomes a problem when I need to move or resize the elements because the control is already assigned to a particular row and column. I could try to use this method and then remove any rows/columns after placing the controls, but I don't think that would work well.
I've also considered a Viewbox, but that's not practical in my case for fairly obvious reasons (as it merely resizes the controls to fit the screen). I'd prefer not to use this because I would only need it to standardize my initial layout. That's it. I also don't want to mess up any text that will be displayed on the window.
So yeah, this is more of a "best practice" question because any solution I can think of would not look very professional or elegant. Feel free to ask any questions if you need clarification.
Edit: As an additional note, I'd prefer to stick with a Grid as opposed to a Canvas as my container.
Edit 2: Just to be clear, I would not need the specific (inital) layout after the first launch. When the program exits, the layout (Margins, Width & Heights, etc. for each element) is saved to a file to use for the next launch.
I've developed a number of kiosk/interactive applications using WPF. If you are trying to show the element transitions (while moving), then it might be best to use a parent Canvas and bind the Canvas.Left and Canvas.Top properties. You can mimic the grid alignment, using a Canvas, if you put in place mechanisms (e.g. Manipulation/Mouse events, converters) to make sure that the Canvas attached properties adjust to the row/column offsets.
It is not uncommon at all to use the Viewbox to mitigate display differences (and your use case is not "rather unique"). You set the Viewbox to a target resolution (e.g. 1920x1080) and allow the control to fill the available space. The other alternative would be to dynamically apply a content template based on the application window size/ratio.
After looking at multiple options, I've decided to just use a calculation to (sort of) simulate the behavior of rows/columns. Because my application is fullscreen, I can take my SystemParameters.PrimaryScreenWidth and SystemParameters.PrimaryScreenHeight to orient my layout. Using a combination of universal padding (static values) and ratio-based calculations (dynamic values), I can smoothly set my initial layout.
For instance, I'm dividing the width of my monitor by 6 (rounded up to avoid decimals) and using that (minus half the control's width) as the control's Margin.Left property, centering it on a 'column' of sorts.
Honestly, my initial layout is fairly simple right now, so we'll see if this will suffice going forward. Thanks to everyone who contributed to the question, and sorry if I was unclear on what I was asking.

Ungroup panels?

So I am working on a program that has several screens which causes it to have overlapping controls (Buttons and lists).
I put the controls in panels which works great and then do show/hide for the panels.
This also works well.
I am having a problem now that I am up to several panels where when I move one panel up it gets absorbed by another and I need them to stay separate.
Example: When I move panel2 into place over panel1, panel2 becomes part of panel1. Then when I do panel1.Hide() and panel2.Show(), panel2 is still hidden because it is part of panel1. is there a way for me to ungroup these or move panel2 into place without it automatically becoming part of panel1? (I know I can show hide the controls inside of the panels, but this will add a lot of complexity because I have a ton of controls)
Perhaps there is a better solution than using panels?
You can use the View + Other Windows + Document Outline tool window to get these panels separated again. Drag the inner panel back to the parent. You'll then also have to edit the Location property to get it back in the right position.
This is annoying of course and good odds that you'll have to do this repeatedly. There's a better way to go about it, a TabControl has good design-time support and also has the same "overlapping panel" metaphor. You just need to hide the tabs at runtime. That's pretty easy to do, check the StackPanel control in this answer.

Drawing Custom Control above all other controls (previously added)

I have a UserControl that adds other UserControls, but I want the "latest" control added to be topmost so it's above the others. Because the controls should be overlapping eachother. Like a card game. So I add 5 controls, the first one should have the least priority the latest the most priority - most visible.
Any ideas?
Or do I have to override the Paint method for the "container" control? And Control.CreateGraphics() and draw it?
Consider BringToFront and SendToBack methods of the Control class.
Check out answers to these questions too
How to set Z-order of a Control using WinForms
Bring Winforms control to front
Just use userControl1.BringToFront() when you add the new control.
Note however, that won't prevent the user from "tabbing" into the controls that are underneath it. For that, you need to disable or make invisible the other controls.
In Windows Forms, the order in which controls are added to their parents' Controls collection determines the order of their rendering.
This means that either you handle the addition of child controls in code and use the appropriate insert positions, or you move the controls around in the designer (which, unfortunately, often means dangerous hand edits to the *.Designer.cs file).
I recommend that you go for the first approach, which is the only feasible method for larger WinForms projects anyway, and make the control insertion logic explicit in your code. The good news, by the way, is that there is no need to tinker with paint handlers, so your worry about hacks like using CreateGraphics() is unjustified and dispelled :)

Graphical hiccups in C# User Control - Resize obscures components

I'm experiencing difficulty with a custom-made User Control, and my searching on Stack Overflow, MSDN, and Google didn't pop up any troubles quite like the one I'm experiencing.
I have a very simple User Control: It's a label, a text box, and a button, with a SaveFileDialog and a FolderSelectDialog available. The text box and button are anchored Left,Right and Right respectively, with the intent that if the control is resized larger, the text box will enlarge to fill the gap, and the button will stay on the right edge of the control.
The problem I am encountering is that when the control is enlarged, the area to the right of the default width of the control becomes blank space when the project is built and run. The pictures here will illustrate what I mean:
In editor:
Running:
The control is smallish in its design window, but when I add it to a form and widen it, it behaves as intended. However, when I run the form the control was added to, half the control isn't visible.
I suspect that I'm overlooking something fairly straightforward, but I wasn't able to find anything addressing this point in my search. Help would be much appreciated.
My guess is that there is a panel or something that is added to your control and will be brought to front somehow runtime.
from property window's top there's a combo from which you can select all the controls in your User Control.
check if all the controls are what you want.
if you find that panel or anything delete it :)
EDIT:
alright this was not your problem.
now I can only assume that you have set some manual sizes to your user control, i.e. in its constructor. in that case designer will show the correct size of you user control,
now some other place in your code, you have set the user controls size manually again. if the layout is suspended and size changes, I think that the anchored controls' size will not change automatically.
if this is your problem, it is probably hard to find.

C#: strange rendering in WinForms

For some reason the labels for "Date From" and "Date To" are rendering strangely on their bottom edges. See how the datepickers are not rendered correctly because of this.
Anyone know why this is occurring? It only occurs when I start the app from the exectuable. It doesn't happen in the IDE.
It looks like the bounds of the Label controls are spilling over into the DateTimePicker controls. Even when a WinForms control has a transparent background, it is not guaranteed to play nice with other controls in the same container. Try reducing the margins/padding on the labels or select both DateTimePicker controls and use the "bring to front" option.
They have a backcolor that matches the form's backcolor.
There are multiple ways to solve this:
Right-click on the label and choose "Send to Back"
Right-click on the other control and choose "Bring to Front"
Make sure the label's AutoSize property is set to true and move it up a little until it doesn't show
Make sure the label's Padding property is 0, 0, 0, 0 (zero for each subproperty)
It's frighteningly easy in VS to accidentally change the size and location of controls when manipulating them with the mouse. You may just have to move/re-size them so they don't overlap. Try moving with the arrow keys or explicitly giving them numeric position and size values.
As mickeyf notes, it's very easy to accidentally move or resize a control.
To reduce the likelihood of this happening, VS allows you to lock controls. If you right click anywhere on the form, and select "Lock Controls", this will lock every control on the form. I always found this to be too draconian, and rarely used it.
But what I somehow missed until very recently, each control has a "Locked" property that can be set individually. I find this much more convenient - you just lock the controls that tend to be problematic.
For example, I have several forms that have a toolbar at the top, and another control that exactly fills the rest of the form. It's very easy to accidentally bump this control by a pixel or so, and not realize it. Now I just lock those controls, which is way more convenient than locking everything.

Categories