Is there a simple way to change the order in which controls are displayed within a panel? I do not mean Z-Index. I mean explicitly setting the 'flow order'. Thank you.
The StackPanel and the Grid use a Children property of type UIElementCollection
By using Remove(At) and Insert you could change the order of the elements in the collection.
After that it depends on the Panel (Grid, Stack, Dock, ...) whether or not, and if how, it uses this order.
Some Panels, such as the Grid, also use attached properties (Grid.Column, Dock.Top) to position elements so there is no single way of re-ordering for all panels.
If the elements are added dynamically through data binding, re-ordering the data items in their collection might cause the Panel to display the controls in a different order.
Related
I have created a FlowLayoutPanel where labels are added dynamically, the label data is taken from a datagridview. Is it possible to sort those labels using a Date column from the datagridview?
A flow layout panel will keep it's child controls in the order that they are added to it.
This means that you can't sort the controls on it.
Your only options are either to remove all the labels and add then in a different order, or to use a regular panel and then sort the existing label by changing the location property of all the labels.
The first option is, of course, much easier.
It is possible to order items of any container using the SetChildIndex method.
Here is an example of how to move an item up one place:
myControl.Parent.Controls.SetChildIndex(
myControl, myControl.Parent.Controls.GetChildIndex(myControl) - 1)
How can I dynamically add a user control to my form and making sure it is aligned properly? In other words, what's the easiest way to control how things are aligned (centered, vertically, horizontally, etc.) when adding it dynamically to my form?
I found the following that works:
http://www.vcskicks.com/align-user-interface.php
One option if you want to explicitly define the location of each new control:
lets say you have a list of objects that you want to create controls for but in different instances you may have a different number of objects in the list. You can loop over the list, instantiating a new control for each item, and placing that control on the form or in another control(like a layout panel) and then explicitly assign the properties of the new control, specifically the location.
Say you want all of your dynamically added controls to be lined up vertically;
assign newcontrol.Location = new System.Drawing.Point(550, offset);
and increment offset by the desired spacing each time you go through the loop.
Suppose I have an element (in my case, a StackPanel) that contains several UI elements (in my case, lots of textboxes contained in various Grids contained in etc.etc. contained in the StackPanel).
I want to know whether any one of those textboxes has focus. (I want to bind this property to a View-Model property.) Is there a property for this? If not, what is the simplest way to bind to this kind of information, without having to first extract all the textboxes? (They’re generated by templates.)
You could use IsKeyboardFocusWithin. What kind of binding are you wanting to do to it? If it's something simple like you're wanting to change the background of the stackpanel if a textbox within has focus, you should be able to use this as a style trigger.
Ultimately, my aim is to have a grid (by grid I mean rows and columns, however it's achieved) of small stack panels to represent time intervals throughout a day. Not too disimilar from the following I suppose (simple calendar-type layout on the right):
(source: msdn.com)
I need a way of creating this grid dynamically and naming the panels appropriately for whenever an event is fired (to be specific - a drop event, each panel's drop event will be wired to the same method in which I must distinguish what panel (i.e. at what point in the day, and on what row) the item was dropped on).
Thanks a LOT for any help!
Dan
You probably won't get the full code to do that from here, but I can point you in the right direction.
You are probably going to want to use nested ItemsControl. I have done something like this in the past where my outer ItemsControl for the Calendar was a Grid, and grid cell contained an inner ItemsControl with a StackPanel of TaskItems.
The most important part is getting your data layer right. I used CalendarDayModel classes, which had a Date property and an ObservableCollection<TaskModel> list. It also had Commands to handle user events, such as double-click events.
My outer ItemsControl was bound to the ObservableCollection<CalendarDayModel> and the inner ItemsControl were bound to the ObservableCollection<TaskModel>
I have some examples of an ItemsControl here, but take note of the last example that uses a Grid.
I am using a Panel to hold a list of controls (user-defined). The way that I add the panels, I am setting the location of the control based on the Panel.Controls.Count before I add it to the panel.
comRec.Location = new Point(comRec.Location.X, panel1.Controls.Count * 25);
panel1.Controls.Add(comRec);
Now, this works nicely and looks exactly the way that I want it to. However, once we reach the limit on the window, the AutoScroll enables (which I do want). Now, if the user were to scroll to the bottom of the Panel, this ultimately changes the location of every control in the panel. Instead of my first comRec.Location being (0,0), it is something like (0,-219). So now, when the user adds another comRec object, it creates a HUGE gap between the objects.
My question is this, what is the best way to account for the changes of the location with the scrollbar and still using my adding system. I am assuming that will have to do something with checking the value of the scrollbar and using it to determine the location.
Also, is there a BETTER way to display a list of controls? Should I be using a Panel?
Look at the FlowLayoutPanel control, it's exactly what you what.
You could add an additional panel into the hierarchy:
Outer panel (scrollable)
Inner panel (not scrollable, resize it whenever you add a control)
User Defined Control 1
User Defined Control 2
User Defined Control 3
User Defined Control 4
...
This way, your additional controls' locations would be relative to their direct parent, the non-scrolling panel.
If you add several controls, try to suspend the layout of the panel while adding the controls:
panel1.SuspendLayout();
// Add controls ...
panel1.ResumeLayout();
This helped me in a similar situation where the user could change dynamically the visibility of existing controls.