Move contents of Form when a Control is re-Located - c#

Let's just say that I have many controls on my Form, and when a User clicks on one of them, its height will expand. This means that, currently, when this clicked-control expands, other controls below it will become overlapped by the expanded control.
But what I want to happen, is for each Control below the expanded control to slide down, so that they are below the expanded control again.
I know how to handle sliding, but I just don't know how to make every control except for one move everytime a given control is moved.
Any help at all is greatly appreciated, thank you!
This is what I was thinking:
void newOrderReceived(object sender, EventArgs e)
{
foreach(Control OrderNotificationBox in OrdersPanel.Controls)
{
if(OrderNotificationBox is NotificationBox) // Checks to see if the control is a NotificationBox
{
// Add my code to slide controls down.
}
}
}
But... How do I know if the control is below the expanded control?
Is this how I should go about changing the location of all controls below the expanded control?
Edit: Just had a thought, to check to see if a NotificationBox is below the Expanded NotificationBox, see revised code below:
void newOrderReceived(object sender, EventArgs e)
{
foreach(Control OrderNotificationBox in OrdersPanel.Controls)
{
if(OrderNotificationBox is NotificationBox) // Checks to see if the control is a NotificationBox
{
if(OrderNotificationBox.Location.Y <= ExpandedNotificationBox.Location.Y + ExpandedNotificationBox.Size.Width)
{
// Add my code to slide controls down.
}
}
}
}
But would this be sufficient? Currently, this is working, so I guess I just answered my own question. But, isn't there a better way to do this? A more elegant/efficient way?
Here's a sample of how it should look:

FlowLayoutPanel provides you with dynamic layout where you can resize any control in it and all below controls will slide automatically. There are many strategies to using groups/columns of flow layout panels to be able to achieve the desired look for the whole form. Some googling will reveal some of these.
For instance in the form above, resizing the button1 control simply flows all the below controls to further down on the form. You can try that at the design time also. Drop the form a flow layout panel, drop 3-4 control in the container and start experimenting..

For each expandable content use Panel.
Dock your panels one under another (Use panel1.Dock = DockStyle.Top. For the very bottom panel use panel1.Dock = DockStyle.Fill).
Place your child controls inside of each expandable panel, set inner controls' Anchor properties accordingly.
When you expand one panel, the rest of the panels will adjust automatically. You don't need to code for this. You will only change Height of a panel that you currently expand.

What you need is some kind of 'ExplorerBar' functionality. There are several control libraries that offer that, and I found the article here on the CodeProject that has it for free.

Related

Recommended way to manipulate User Control panels into a Windows From

I just started working with Visual Studio C# and to be honest I didn't fully understand what happens when we chose to hide a form or a user control.
My intuition tells me this hide/show method is kind of "inefficient" way to get an user through all the functions of my app.
So I am asking you guys if there is another workaround to "load" user control parts in a form.
Right now my main_menu form has all the user control objects placed on the form, but hidden, and I am using buttons to show them.
Is there a better way to achieve the same result? (I was thinking of a workaround like having an empty panel where I can load the User Control - not sure if possible)
Thank you!
You can create the controls on the fly and add them to or remove them from the Controls collection. On the class level, define this field
private Control _currentPanel;
You can use a more specific type here, if you are deriving all your panels from a common base type.
Then change the panel with
// Remove previous one.
if (_currentPanel != null) {
Controls.Remove(_currentPanel);
}
// Add new one
_currentPanel = new MyNewPanel();
//TODO: possibly set the panels Docking property to Fill here.
Controls.Add(_currentPanel);
In the example I am working with the form's Controls collection; however, you might have to use the Controls collection of some container control holding the panel.

Tags in WinForms TextBox

I want to create a textbox on a WinForms form, where the user cannot input text directly. Instead, the content of the textbox should only be "bubbles" (with a "delete" button), showing a text value.
I'm struggeling to find the correct term for this kind of control/behaviour. It should look a bit like the "Tags"-field on StackOverflow when creating a new question.
Are there any existing controls/settings that allow such behaviour? (I have DevExpress if that helps)
Sorry for the vague question, if i knew better terms for what i'm looking for, i'd probably find something...
Instead of a textbox, the container for your bubbles should most likely be a Panel.
You can style it as needed, set the border, background color, etc.
If you don't want to manually position the "bubbles" inside it, use a FlowLayoutPanel. It will automatically put it's children controls in a flow.
Check out the properties of the control to specify how you want controls to be laid out.
The individual bubbles can also be Panels or other container controlls, so that you can add a label and a button (or image to serve as a button) to each.
You might even extend the panel class to automatically add a label and a delete button to each.
something like this (please note this is more like pseudo code. I wrote it up of the top of my head here, some adjustment may be needed)
Public Bubble : Panel {
Public Bubble(string text) {
Label title = new Label { Text = text };
Controls.Add(title);
Button delete = new Button { Text = "Delete" };
Controls.Add(delete);
//also hook up events here, ie delete.click+= whatever
}
}
You can further extend the custom class for your specific needs.
Set styles on the button and label as needed to achive the look you want.
Don't forget to hook up events such as mouse over, button click, etc.
Then just fill the FlowLayoutPanel with these custom controls and you should be good to go

How can I set a panel to be always on top when changing tabpages in C#?

I have program with two tabs in a TabController, I also have a panel I want to always have in front. Despite what tabpage I am in. I tried setting the panel to BringToFront(), but that donĀ“t seem to work when I change tabpage. Any suggestions how to solve this?
If the Panel is contained by the TabPage, then you'd have to manually switch it to the current tab whenever the tab changes, then call BringToFront().
An alternative would be to make the Panel so it's directly contained by the Form, but in front of the TabControl (like it's "floating" over it). Then it would just stay there. You'd have to either manually fiddle with the Panel's Location() property to get it right (you couldn't drag it over the TabPage as then it would drop into it), or you could position it properly via code in the Load() event of the Form.
Edit:
For instance, if you properly positioned "panel1" in the TabPage at design-time, you could switch it to the Form using code like this:
private void Form1_Load(object sender, EventArgs e)
{
Point pt = panel1.PointToScreen(new Point(0, 0));
panel1.Parent = this;
panel1.Location = this.PointToClient(pt);
panel1.BringToFront();
}
Set the panel outside the tabcontroller and set it's dockstyle. Also set the dockstyle of the tabcontroller.
Panel belongs to a specific tabpage. When you change to another tabpage and call BringToFront(), it doesn't make anything, because you're on another tabpage right now. So you need to workaround that with righting some code. There are two ways:
1) You can place that panel on every tabpage in design time (if you don't need some shared data on that panel).
2) You should hook OnTabPageChanged event and move panel from old tabpage to the page you switched to (if you do need some shared data on that panel). I think this is your case.

Indexing into Controls Collection on Tab Control

I have a C# Forms tab application. Each TabPage has a menu on the left (Outlook style navigation panel), and a Panel on the right for content.
If I want the content panel for tab page 0, how would I go about fetching it? I'm a bit stumped because I don't know how to index into the controls collection on a tab page. The following is underlined in red, so I believe its wrong.
Panel panel = tabControl.TabPages[0].Controls["Panel"];
EDIT: remove Window in Panel sub question. It will be moved to a separate question.
Sorry about the beginner questions. I'm a C/C++ guy with lots of MFC time, and C# UI is a bit frustrating at the moment.
foreach (Control control in tabControl1.TabPages[0].Controls)
{
// if (control.Name == "panel1")
}
You can always call this recursively on control.Controls to find a control in any hierarchy. control.Name can be used to find your specific control.
You can't show a Form, inside a Panel. You could create Custom Control where you can add your functionality and add that control to a Panel.
in order to create a new form for example you need to create a variable of what ever form that it is you want to create.
example
Form2 frm2 = new Form2();
frm2.Show();
if you want to show that form in the panel then the panel would be the Owner keep in mind the difference between Owner and Parent
please paste what ever code you have so far and we can suggest the necessary changes
Finally, how does one display a Window in a Panel? - you don't want to do that. If you want a window and a panel to share a piece of UI functionality, create a user control with all the the functionality and then you can place it in a form or in a panel.
A possibility to encapsulate complex UI content is to create a UserControl. This way you can create a reusable piece of complex UI you can basically add as a "blob" inside a form.
The reason why
Panel panel = tabControl.TabPages[0].Controls["Panel"];
is underlined red is because the Controls collection returns a Control which might be a Panel but also might be something else. So you need to cast it:
Panel panel = tabControl.TabPages[0].Controls["Panel"] as Panel;
if (panel != null)
{
// got a panel here so do something
}
Also: MSDN has some good resources - you should make use of it.

autoscroll panel to bottom

i have a panel in my winforms and in it i load some usercontrols .
i would like to autoscroll to the bottom of the panel( as my panel fills ) everytime a new usercontrol is added . How can i do so ?
You can do that by setting the VerticalScroll of the Panel but I think it would be better to use ScrollControlIntoView instead.
private void panel1_ControlAdded(object sender, ControlEventArgs e)
{
panel1.ScrollControlIntoView(e.Control);
}
Good luck!
You could use ScrollControlIntoView and pass the control you last added.
An alternate solution would be:
panel.VerticalScroll.Value = panel.VerticalScroll.Maximum
I found that continuously adding controls to the panel at vertical increments would be affected negatively whenever a user had scrolled the panel up or down. I used the tip from Homam above, and found the following to work well:
panel1.VerticalScroll.Value = 0;
// Creating and adding a TextBox, tb, to the panel
panel1.ScrollControlIntoView(tb);
So first, I scroll to the top in order to use absolute vertical positions for my text boxes, then I place the Text Box, and finally, I make sure that the newly created text box comes into view.

Categories

Resources