How to keep the SplitBar when panel collapsed in SplitContainer? - c#

I found that when a panel collapse in splitcontainer, the splitbar is hided either.
splitContainer1.Panel2Collapsed = true;
I would like to use double click the split bar to toggle panel2.
How to keep the split bar when one panel is collapse?

Don't collapse it:
sc.Panel2MinSize = 0;
sc.SplitterDistance = sc.ClientSize.Width - sc.SplitterWidth;

Related

FlowLayoutPanel FlowDirection issue

I'm trying to add x Buttons to a FlowLayoutPanel which is docked (DocType fill) in a Panel.
I have set the FlowDirection to Topdown as I want something like:
However, the FlowLayoutPanel has a horizontal scrollbar, not a vertical one:
I add the buttons like this:
flowLayoutPanel1.Controls.Add(new Button { Text = "Chat", Width = flowLayoutPanel1.Width - flowLayoutPanel1.Margin.Left - flowLayoutPanel1.Margin.Right});
I also tried:
flowLayoutPanel1.Controls.Add(new Button { Text = "Chat", Dock = DockStyle.Fill});
And also:
flowLayoutPanel1.Controls.Add(new Button { Text = "Chat", Anchor = AnchorStyles.Left | AnchorStyles.Right});
I tried this and also looked here. Both don't work for me.
Thanks for your help.
after some digging here I found it out.
I had to set the FlowLayoutPanel.WrapContents Property to false.

How to reproduce a forum/twitter-like UI on Winform

As a classic forum, threads and replys are displayed on a page, with dark and light and dark and light backcolor.
I am trying to write a client of a forum on windows using winform. It is
At first, I have tried this way:
Add a big panel to the form, let's call it the PARENT PANEL.
Add small panels to the big panel like this:
panel1.Visible = false;
for (int i=0; i<5;i++)
{
Panel parent = new Panel();
parent.Height = 800;
Random ra = new Random();
TextBox p = new TextBox();
p.Text = "fehsuifq";
p.Multiline = true;
p.WordWrap = true;
p.Dock = DockStyle.Fill;
parent.BackColor = Color.FromArgb(ra.Next(0, 254), ra.Next(0, 254), ra.Next(0, 254));
p.BorderStyle = BorderStyle.None;
p.ReadOnly = true;
p.TabStop = false;
p.BackColor = this.BackColor;
parent.Controls.Add(p);
parent.Dock = DockStyle.Top;
panel1.Controls.Add(parent);
}
panel1.Visible = true;
Every panel(tenicially, a control) displays a thread's text and images and others details(like authors or avator).
Images are not shown until it is clicked.
when the image is clicked, it is loaded and the controls's height will change as result.
The PARENT PANEL will contains hundreds of these controls since there will be so many threads. It is and have to be scrollable, obviously.
But if I put a textbox in the control, the scroll wheel no longer work on the PARENT PANEL.If I use a label, it is not selectable.
I think this way can't be more stupid, completely.
So I am looking for a better to do this job, to display hundreds or even thousands threads/replys on winform, which is:
the height is dynamic, because the images inside will not load until it is clicked.
The text inside is selectable (I edited this just to disambiguate)
the PARENT PANEL can response to the mouse's wheel, just like twitter, forums.
So that I can use my scroll wheel to browse all the replys at one time. The loading is a background work.
Look at the picture, when the text is selected, the whole panel is still response to the wheel(just like normal webPage). This is a uwp app and I am not sure if winform can do this.

Unable to scroll to the bottom of WinForm

I am using visual studio 2012 for this. Basically I have a WinForm that I want to expand.
Inside the form designer, I am able to see that my form has a scroll bar, but when I compile the program, the scroll bar does not appear. The controls that are beyond my screen size are clipped off, as opposed to having a scrollbar.
Are there any settings that I have missed out? Currently I set my AutoScroll = true.
Scrollbars show up when a parent control has the AutoScroll set to true and a child control has a MinimumSize such that the client area of the child control is larger than the client area of the parent control.
E.g.
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var sampleForm = new Form() { AutoScroll = true };
Panel panel = new Panel() { BackColor = Color.Red, AutoSizeMode = AutoSizeMode.GrowAndShrink, AutoSize = true };
Button btn = new Button { Text = "Toggle MinSize", AutoSize = true };
panel.Controls.Add(btn);
btn.Click += delegate {
if (panel.MinimumSize == Size.Empty)
panel.MinimumSize = new Size(600,600);
else
panel.MinimumSize = Size.Empty;
};
sampleForm.Controls.Add(panel);
Application.Run(sampleForm);
}
If your child panel correctly calculates its preferred size, then you can override the MinimumSize property and return the PreferredSize.
AutoScroll = true is enough to display scroll on form no other setting is required.
just try other thing add panel in form and set panels AutoScroll = true and then add control to it and check that scroll is working or not ?
Take a look at the properties of the controls within the container for which you want autoscroll to work. One possibility is that you set one or more of those controls Anchor property to Right or something, which can reverse the autoscroll setting behind the scenes to effectively turn it off. Also check the RightToLeft property of the container, and try setting that to the default "no"
Make sure you have set Dock.Fill i.e. Dock property to Fill
Set property AutoScroll = true , AutoSize = true, AutoSizeMode = GrowOnly ,you can also do this by adding a panel to the form and set panel AutoScroll = true.
compare your issue with example here

Scrollbar location is moving visible/nonvisible changing controls

I have a form with a scrollable panel and two controls sitting right on top of each other - one visible one not. Based on a certain condition when that form is activated I might swap the visible properties of the two controls. These controls are at the bottom of the scrollable panel. If when I leave that form I leave it scrolled to the bottom, go change the condition that will cause the controls' visibility to swap and go back to that form the visible control will have dropped about 200px down the page leaving a large gap. Anyone know what could be causing this? I tried resetting the scrollbar position to the top on form close but that just causes a smaller gap and sometimes the control to move higher into other controls. Any ideas?
Here is an example that reproduces the problem. If the mouse is moved over the red label, the visibility of button2 is changed to true which causes the scroll jumps back up to Button1.
public class Form123456 : Form {
public Form123456() {
Controls.Add(new UC1());
}
public class UC1 : UserControl {
Button b1 = new Button { Text = "Button1" };
Label lb = new Label { Text = "_", AutoSize = true, BackColor = Color.Red };
Button b2 = new Button { Text = "Button2", Visible = false };
Button b2b = new Button { Text = "x" };
Button b3 = new Button { Text = "Button3" };
public UC1() {
AutoScroll = true;
Dock = DockStyle.Fill;
b1.Location = new Point(0, 200);
b2.Location = new Point(0, 600);
lb.Location = new Point(70, 600);
b2b.Location = new Point(90, 600);
b3.Location = new Point(0, 800);
Controls.Add(b1);
Controls.Add(b2);
Controls.Add(lb);
Controls.Add(b2b);
Controls.Add(b3);
lb.MouseEnter += delegate {
b2.Visible = true;
};
lb.MouseLeave += delegate {
b2.Visible = false;
};
}
}
}
To fix it, one solution is to add this code:
protected override Point ScrollToControl(Control activeControl) {
return this.AutoScrollPosition;
}
Solution from:
Why does clicking in a text box cause an AutoScroll panel to scroll back to the top?
No repro. Sounds to me that you are doing more than just changing the Visible property. Whenever you assign the Location property, you have to add the AutoScrollPosition to compensate for the scroll state. Post code if this doesn't help.
Have you verified the order that you change visibility of the two controls?
The scroll bars on a container with auto scroll set to true will appear and disappear depending on the position of controls that are outside of the visible area of the control. Controls that are invisible do not count.
So in your case if you make both controls invisible at anytime, the scroll bars will disappear. They will come back when one control is made visible. So to make sure you don't have a jump in scroll bar position and controls position you should make sure that at no time are both controls invisible. Another solution is to have a pseudo-visible control on the container. That is a control that has its visibility set to true but it is not actually visible for the user (for example a dot of the color of the background, a label with no text ...). Position this control in the furthest position x,y and the scroll bars will never disappear..

event when the scroll bars appear C#

How can you detect exactly when the scroll bar appears in a UserControl? Is there an event for this?
They can only appear when the control is resized or the amount of data in the control increases. Since you get notifications of resize, and adding data is up to you. It's easy to add code to test for the scrollbar in the few places where their visibility can change. There's really no need to have a special notification.
I ended up using the Layout event, and checking if the scrollbars were currently shown or not. A Layout event is sent when the scroll bar visibility changes.
This is more reliable than listening to the size of the window, because the size of the window is not the only thing that can cause the scrollbars to appear.
https://msdn.microsoft.com/en-us/library/system.windows.forms.control.layout(v=vs.110).aspx
Scroll bars are finicky
Working with scroll bars is often arduous. The Layout event solution is correct but I want to add my additional research to the knowledgebase.
I'm attempting to automatically change the width of multiple UserControl inside a custom UserControl that inherits from FlowLayoutPanel. I want a vertical scroll bar to appear only when the list is longer than the panel size. No horizontal scroll bar ever. Your implementation may differ slightly but the bulk of code will be similar and face similar issues.
ScrollableControl
In order for a UserControl to have a scroll bar appear, it must inherit from ScrollableControl. Both Panel and ContainerControl fit this criteria.
ScrollableControl only contains the Scroll event. This event occurs when scrolling but not upon appearance of the scroll bar.
Rather, the Layout Event found inside Control will occur when a control should reposition its child controls. This includes resizing, child resizing, and parent resizing. I would recommend using this event rather than manually checking for resize to avoid unwanted and inconsistent behavior.
Detecting a scroll bar
To detect when the scroll bar should appears, I count the number of controls in the FlowLayoutPanel and compare it against the number of "visible controls". Visible controls are those which intersect the border area of the panel.
private void RichFlowPanel_Layout(object sender, LayoutEventArgs e)
{
var controls = Controls.Cast<Control>().OrderBy(x => x.Top);
var visibles = controls.Where(l => ClientRectangle.IntersectsWith(l.Bounds));
if (visibles.Count() <= Controls.Count)
{
// A scrollbar exists
}
else
{
// A scrollbar does not exist
}
}
Derived from this answer.
Controlling a scroll bar
A scroll bar can automatically show/hide by setting AutoScroll=true. This will also display the horizontal scrollbar if there isn't space for the vertical scrollbar. AutoScroll opens a Pandora's box of scrollbar issues & bugs. In order to keep the horizontal scrollbar hidden, AutoScroll must be false. This answer outlines a work around for keeping the horizontal hidden.
Specifically
panel.HorizontalScroll.Maximum = 0;
HScroll = false;
panel.VerticalScroll.Visible = false;
will hide the horizontal scroll bar.
The usage and odd behavior of HScroll is covered in this answer.
Combining what we've learned
The following event method is attached to the Layout event inside my custom user control extending FlowLayoutPanel.
Point prevPosition;
private void RichFlowPanel_Layout(object sender, LayoutEventArgs e)
{
var controls = Controls.Cast<Control>().OrderBy(x => x.Top);
var visibles = controls.Where(l => ClientRectangle.IntersectsWith(l.Bounds));
prevPosition = AutoScrollPosition;
if (visibles.Count() <= Controls.Count)
{
Console.WriteLine("showing scroll bar" + " V: " + visibles.Count() + " C: " + Controls.Count);
VerticalScroll.Visible = true;
// Insert method here to tell children controls to resize
HorizontalScroll.Maximum = 0;
HScroll = false;
HorizontalScroll.Visible = false;
}
else
{
Console.WriteLine("hiding scroll bar" + " V: " + visibles.Count() + " C: " + Controls.Count);
VScroll = false;
VerticalScroll.Visible = false;
// Insert method here to tell children controls to resize
HorizontalScroll.Maximum = 0;
HScroll = false;
HorizontalScroll.Visible = false;
}
AutoScrollPosition = new Point(Math.Abs(AutoScrollPosition.X), Math.Abs(prevPosition.Y));
}
Additionally, InitalializeComponents() of the FlowLayoutPanel for completeness and because docking, AutoSize, etc. can often bring confusing behavior.
this.SuspendLayout();
//
// RichFlowPanelUserControl
//
this.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.AutoSize = true;
this.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
this.Padding = new System.Windows.Forms.Padding(3);
this.WrapContents = false;
this.Layout += new System.Windows.Forms.LayoutEventHandler(this.RichFlowPanel_Layout);
this.ResumeLayout(false);
I understand this is slightly off-topic but the combination of this information should help users on their scroll bar adventures.
Why not use the "ClientSizeChanged" event?
This event gets fired if the client size has changed, which is the case if a scrollbar is added.

Categories

Resources