SplitContainer "Continuous Layout" or "Show Contents During Reizing" Option?

Hello,

I am working with the SplitContainer control in VS .NET 2005 July CTP.

When sizing a content area on the screen, such as when resizing a form or when moving a splitter bar, there are usually two ways to go about it. One is to draw the splitter bar / form bounds only, then resize and repaint the content area(s) and child controls once, when resizing is complete.

The second way is referred to in Java as "Continuous Layout" and, I believe in Windows as "Show Window Contents During Resizing" (an OS-controlled option in Windows).

I am trying to get this continuous resizing behavior with the SplitContainer control, such that the two SplitContainer panels are dynamically resized, continuously, as the splitter bar is moved.

I've tried hooking into a few events on the SplitContainer, and calling Invalidate() / Refrehsh, but so far haven't had much luck. I believe this behavior is possible, since resizing the SplitContainer itself causes the actual SplitContainer Panels to resize because the proportions of the internal panels are (appear to be) maintained during SplitContainer resizing.

I like the user experience that this provides (AERO, right! :) ) so would be grateful for any pointers or comments.
Thank you,

--Mike

[1262 byte] By [MikeP2] at [2007-12-16]
# 1
I've posted a suggestion on the MSDN Product Feedback Center:

SplitContainer should have an option to continuously repaint panel contents WHILE resizing: "Show Panel Contents While Resizing" / "Continuous Layout"
http://lab.msdn.microsoft.com/productfeedback/viewfeedback.aspx?feedbackid=d82f876f-12de-4a53-a591-8d88d36e7623

MikeP2 at 2007-9-9 > top of Msdn Tech,Windows Forms,Windows Forms General...
# 2
Hi Mike,

As I stated in the attached bug we won't be able include this functionality into the SplitContainer itself in this release, however the following workaround will give you the desired results.

A nice side effect is that it will cause the splitter to not steal focus like you requested in your other posting (http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=69511), and does so in a slightly cleaner and more efficient way. (So you don't need the code from the other posting anymore.) In addition, it still allows tab stop for keyboard control if you want that functionality. Finally it is formatted in a way that you can assign multiple SplitContainers these same events so you don't have to rewrite this code for each one.


private void splitContainer1_MouseDown(object sender, MouseEventArgs e)
{
/* This disables the normal move behavior */
((SplitContainer)sender).IsSplitterFixed = true;
}

private
void splitContainer1_MouseUp(object sender, MouseEventArgs e)
{
/* This allows the splitter to be moved normally again */
((
SplitContainer)sender).IsSplitterFixed = false;
}

private
void splitContainer1_MouseMove(object sender, MouseEventArgs e)
{
/* Check to make sure the splitter won't be updated by the
normal
move behavior also */
if (((SplitContainer)sender).IsSplitterFixed)
{
/* Make sure that the button used to move the splitter
is the
left mouse button */
if (e.Button.Equals(MouseButtons.Left))
{
/* Checks to see if the splitter is aligned Vertically */
if (((SplitContainer)sender).Orientation.Equals(Orientation.Vertical))
{
/* Only move the splitter if the mouse is within
the
appropriate bounds */
if (e.X > 0 && e.X < ((SplitContainer)sender).Width)
{
/* Move the splitter */
((SplitContainer)sender).SplitterDistance = e.X;
}
}
/* If it isn't aligned vertically then it must be
horizontal */
else
{
/* Only move the splitter if the mouse is within
the
appropriate bounds */
if (e.Y > 0 && e.Y < ((SplitContainer)sender).Height)
{
/* Move the splitter */
((SplitContainer)sender).SplitterDistance = e.Y;
}
}
}
/* If a button other than left is pressed or no button
at all */
else
{
/* This allows the splitter to be moved normally again */
((
SplitContainer)sender).IsSplitterFixed = false;
}
}
}



Hope this helps.

Scott Morrison
WinForms PM
Microsoft Corp.

Scott_Morrison at 2007-9-9 > top of Msdn Tech,Windows Forms,Windows Forms General...
# 3
Hi Scott,

Thanks again so much for your tremendous effort here.

I was able to drop in your code, hook up a few events, and was successfuly able to get the dynamic resizing / continuous panel layout while moving the splitter.

Please Note that in order to get my desired result, I had to put a splitContainer1.Refresh() call after the end of the appropriate (Vertical, in my case) ((SplitContainer)sender).SplitterDistance = {...} line. Without it, the panels would not redraw completly with each movement of the splitter--they would only redraw after the splitter had been paused for a while.

In the end, this was the desired result as was after. However, I must say that the effect isn't quite as clean as I had hoped--background panels peek out momentarily, controls appear to "jump". This is not an issue with just me--try resizing (continuously!) the Word 2003 "Task Pane" on the right. You'll notice similar artifacts.

So I am now able to try things both ways. We'll see if the .NET framework window painting code gets improved performance-wise in the post-beta bits, although I suspect this may be a native issue.

Thank you again--great work and great customer/developer relations.

MikeP2 at 2007-9-9 > top of Msdn Tech,Windows Forms,Windows Forms General...
# 4

Is there a way to the same thing for VS 2003.

I tried putting two horizonitlal splitter bars in panels and when the top splitter is moved the lower one will move with it. Is there a way to do this?

Thanks

Marty

mjorg at 2007-9-9 > top of Msdn Tech,Windows Forms,Windows Forms General...
# 5

I originally spent a day figuring out a workaround with the old splitter control of past VStudio versions which simply enough was to add the below code snippet... when I realized the splitter had been replaced in 2005 I tried a similar approach to no avail. So, I just went back to the using the old splitter control in my new projects :)

Cheers,

Chris

private void splitter1_SplitterMoving(object sender, System.Windows.Forms.SplitterEventArgs e) {

splitter1.SplitPosition=splitter1.SplitPosition;

}

xstos at 2007-9-9 > top of Msdn Tech,Windows Forms,Windows Forms General...