Click here to Skip to main content
Click here to Skip to main content

Collapsible Splitter control in C#

By , 26 Aug 2003
 

Introduction

This control was modeled from the collapsible splitter used in the Mozilla web browser, but with some added functionality. This control allows a linked form control to be dynamically expanded and collapsed by clicking on the splitter control button, and resized by dragging the splitter. Additionally, there is an option to expanded or contract the parent form so that the control to expand doesn't take any further form area.

How it works

The CollapsibleSplitter derives from the System.Windows.Forms.Splitter class, working with 2 overrides, mouse event handlers, and exposing 4 new properties. The code is relatively straight-forward, and is well commented. The only code that I will cover here is the control painting and interaction with the base splitter control.

In creating the control, I first started by creating a new derived class with Stephen Toub's DeriveClass utility. The next step was to draw the control surface, first by finding the clip rectangle for the base splitter and then defining a new rectangle located in the vertical center of the splitter for the collapser control.

protected override void OnPaint(PaintEventArgs e)
{
    // force the width to 8px so that everything
    // always draws correctly
    this.Width = 8;

    // create a Graphics object
    Graphics g = e.Graphics;

    // find the rectangle for the splitter and paint it
    Rectangle r = this.ClientRectangle; // fixed in version 1.1
    g.FillRectangle(new SolidBrush(this.BackColor), r);

    // create a new rectangle in the vertical center 
    // of the splitter for our collapse control button
    rr = new Rectangle(r.X, (int) r.Y + ((r.Height - 115)/2),
        8, 115);

    // draw the background color for our control image
    if(hot)
        g.FillRectangle(new SolidBrush(hotColor), 
            new Rectangle(rr.X + 1, rr.Y, 6, 115));
    else
        g.FillRectangle(new SolidBrush(this.BackColor), 
            new Rectangle(rr.X + 1, rr.Y, 6, 115));

    // draw the top & bottom lines for our control image
    g.DrawLine(new Pen(SystemColors.ControlDark, 1), 
        rr.X + 1, rr.Y, rr.X + rr.Width - 2, rr.Y);
    g.DrawLine(new Pen(SystemColors.ControlDark, 1), 
        rr.X + 1, rr.Y + rr.Height, rr.X + rr.Width - 2, 
        rr.Y + rr.Height);

    // draw the arrows for our control image
    // the ArrowPointArray is a point array that 
    // defines an arrow shaped polygon
    g.FillPolygon(new SolidBrush(SystemColors.ControlDarkDark), 
        ArrowPointArray(rr.X + 2, rr.Y + 3));

    g.FillPolygon(new SolidBrush(SystemColors.ControlDarkDark), 
        ArrowPointArray(rr.X + 2, rr.Y + rr.Height - 9));

    // draw the dots for our control image using a loop
    int x = rr.X + 3;
    int y = rr.Y + 14;

    // Visual Styles added in version 1.1
    switch(visualStyle)
    {
    case VisualStyles.Mozilla:
        for(int i=0; i < 30; i++)
        {
            // light dot
            g.DrawLine(
                new Pen(SystemColors.ControlLightLight), 
                x, y + (i*3), x+1, y + 1 + (i*3));

            // dark dot
            g.DrawLine(
                new Pen(SystemColors.ControlDarkDark), 
                x+1, y + 1 + (i*3), x+2, y + 2 + (i*3));

            // overdraw the background color as we actually 
            // drew 2px diagonal lines, not just dots..
            if(hot)
                g.DrawLine(new Pen(hotColor), 
                    x+2, y + 1 + (i*3), x+2, y + 2 + (i*3));
            else
                g.DrawLine(new Pen(this.BackColor), 
                    x+2, y + 1 + (i*3), x+2, y + 2 + (i*3));
        }
        break;

    case VisualStyles.DoubleDots:
        for(int i=0; i < 30; i++)
        {
            // light dot
            g.DrawRectangle(
                new Pen(SystemColors.ControlLightLight), 
                x, y + 1 + (i*3), 1, 1 );

            // dark dot
            g.DrawRectangle(
                new Pen(SystemColors.ControlDark), 
                x - 1, y +(i*3), 1, 1 );

            i++;

            // light dot
            g.DrawRectangle(
                new Pen(SystemColors.ControlLightLight), 
                x + 2, y + 1 + (i*3), 1, 1 );

            // dark dot
            g.DrawRectangle(
                new Pen(SystemColors.ControlDark), 
                x + 1, y  + (i*3), 1, 1 );
        }
        break;

    case VisualStyles.Win9x:
        g.DrawLine(new Pen(SystemColors.ControlLightLight), 
            x, y, x + 2, y);
        g.DrawLine(new Pen(SystemColors.ControlLightLight), 
            x, y, x,y + 90);
        g.DrawLine(new Pen(SystemColors.ControlDark), 
            x + 2, y, x + 2, y + 90);
        g.DrawLine(new Pen(SystemColors.ControlDark), 
            x, y + 90, x + 2, y + 90);
        break;

    case VisualStyles.XP:
        for(int i=0; i < 18; i++)
        {
            // light dot
            g.DrawRectangle(
                new Pen(SystemColors.ControlLight), 
                x, y + (i*5), 2, 2 );

            // light light dot
            g.DrawRectangle(
                new Pen(SystemColors.ControlLightLight), 
                x + 1, y + 1 + (i*5), 1, 1 );

            // dark dark dot
            g.DrawRectangle(
                new Pen(SystemColors.ControlDarkDark), 
                x, y +(i*5), 1, 1 );

            // dark fill
            g.DrawLine(
                new Pen(SystemColors.ControlDark), 
                x, y + (i*5), x, y + (i*5) + 1);

            g.DrawLine(
                new Pen(SystemColors.ControlDark), 
                x, y + (i*5), x + 1, y + (i*5));
        }
        break;

    case VisualStyles.Lines:
        for(int i=0; i < 44; i++)
        {
            g.DrawLine(new Pen(SystemColors.ControlDark), 
                x, y + (i*2), x + 2, y + (i*2));
        }

        break;
    }

    // dispose the Graphics object
    g.Dispose();
}

The control rectangle is used in the MouseMove event to determine if the cursor is within the control area (hot), or in the base controls splitter area.  Once we know whether the cursor is in the 'hot' area we can change various aspects of the control:  use a highlighted background color, ignore or pass on the MouseDown event, and also set the appropriate mouse cursor.

// this method was updated in version 1.11 to fix 
// a flickering problem discovered by John O'Byrne
private void OnMouseMove(object sender, MouseEventArgs e)
{
    // check to see if the mouse cursor position is within 
    // the bounds of our control
    if(e.X >= rr.X && e.X <= rr.X + rr.Width && 
        e.Y >= rr.Y && e.Y <= rr.Y + rr.Height)
    {
        if(!hot)
        {
            hot = true;
            this.Cursor = Cursors.Hand;
            this.Refresh();
        }
    }
    else
    {
        if(hot)
        {
            hot = false;
            this.Refresh();
        }

        if(!controlToHide.Visible)
            this.Cursor = Cursors.Default;
        else
            this.Cursor = Cursors.VSplit;
    }
}

protected override void OnMouseDown(MouseEventArgs e)
{
    // if the hider control isn't hot, 
    // let the base resize action occur
    if(!hot && !collapsed)
        base.OnMouseDown(e);
}

Using the control

The CollapsibleSplitter control can be added to the toolbox using the pre-compiled dll in the demo application, or simply copy the class into your project and manually reference it in your code.

To Add the Collapsible Splitter to your VS.Net toolbox, follow these steps:

  • Right-click on the VS.Net Toolbox and select "Customize Toolbox..."
  • Select the ".Net Framework Components" tab, and click the "Browse.." button
  • Browse to and open the "CollapsibleSplitter.dll" file from the demo application archive
  • Click OK to add Collapsible Splitter control to your Toolbox.

Once you have it on a form, set the Dock property, and then set the ControlToHideproperty so that the splitter knows which form control to interact with. All properties specific to the collapsing behaviour can be found under the Collapsing Options group in the properties window. Once created on your form, the view state can be programmatically toggled by calling the ToggleState method, and the current state can be retrieved from the IsCollapsed property.

I hope you find this control useful, and if you improve this control, please email me the updated source. If you have any comments or suggestions, please post your thoughts in the feedback section below.

Updates

Version 1.1 Changes:

  • OnPaint is now overridden instead of being a handled event, and the entire splitter is now painted rather than just the collapser control
  • The splitter rectangle is now correctly defined
  • The Collapsed property was renamed to IsCollapsed, and the code changed so that no value needs to be set
  • New visual styles added: Win9x, XP, DoubleDots and Lines

Version 1.11 Changes:

  • The OnMouseMove event handler was updated to address a flickering issue discovered by John O'Byrne

Version 1.2 Changes:

  • Added support for Horizontal Splitters

Version 1.3 Changes: (24 Aug 2003)

  • Added an optional 3D border
  • General code and comment cleaning
  • Flagged assembly with the CLSCompliant attribute
  • Added a simple designer class to filter unwanted properties
  • Added support for inclusion as a VS.Net ToolBox control
  • Added a ToolBox bitmap
  • Removed extraneous overrides
  • Added summaries
  • Removed the ParentFolder from public properties - this is now set automatically in the OnHandleCreated event
  • Added expand/collapse animation code

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)

About the Author

Furty
Web Developer
Thailand Thailand
Member
Furty will code for food.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionNice, but how to use?memberb845985@rmqkr.net8 Jan '13 - 3:08 
I've tried the demo, and it is really cool. But how do I make a new dialog with this control? whenever I add it, it ties itself to one of the edges (where it is docked to), and refuses to be moved and controls won't be moved to the docked side of it.
GeneralMy vote of 5membermanoj kumar choubey3 Jul '12 - 23:46 
Nice
QuestionDo not dispose e.Graphics in Paint eventmemberMember 143012617 Aug '11 - 7:09 
You should not dispose of the Graphics object in the Paint event.
See: http://stackoverflow.com/questions/4316149/c-is-it-neccesary-to-dispose-of-a-graphics-element-inside-a-custom-control[^]
 
Also please add:
this.SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
In the constructor to eliminate flicker
GeneralLicensememberaldo hexosa6 Jul '09 - 16:08 
Nice job. I like your Collapsible Splitter. May I use it in my commercial application?
Generalupdate to new version pleasemembercvckillern8 May '09 - 2:27 
it would be nice if you could update Collapsible Splitter control to the newest version
Questionmemory management bugmemberzxcv093851248522 Sep '07 - 9:57 
use Dispose!!! D'Oh! | :doh: (override Dispose, dispose graphic objects ...)
AnswerRe: memory management bugmemberMember 342740326 Jan '09 - 12:02 
This is a fix for lack of dispose in OnPaint
// OnPaint is now an override rather than an event in version 1.1
        protected override void OnPaint(PaintEventArgs e)
        {
            // create a Graphics object
            using (Graphics g = e.Graphics)
            {
                Pen pen_controlLightLight = new Pen(SystemColors.ControlLightLight);
                Pen pen_controlLight = new Pen(SystemColors.ControlLight);
                Pen pen_controlDark = new Pen(SystemColors.ControlDark);
                Pen pen_backColor = new Pen(this.BackColor);
                Pen pen_hotColor = new Pen(this.hotColor);
                Pen pen_controlDarkDark = new Pen(SystemColors.ControlDarkDark);
 
                Brush brush_controlDark = new SolidBrush(SystemColors.ControlDark);
                Brush brush_controlDarkDark = new SolidBrush(SystemColors.ControlDarkDark);
                Brush brush_backColor = new SolidBrush(this.BackColor);
                Brush brush_hotColor = new SolidBrush(this.hotColor);
 
                // find the rectangle for the splitter and paint it
                Rectangle r = this.ClientRectangle; // fixed in version 1.1
                g.FillRectangle(brush_backColor, r);
 
                #region Vertical Splitter
                // Check the docking style and create the control rectangle accordingly
                if (this.Dock == DockStyle.Left || this.Dock == DockStyle.Right)
                {
                    // create a new rectangle in the vertical center of the splitter for our collapse control button
                    rr = new Rectangle(r.X, (int)r.Y + ((r.Height - 115) / 2), 8, 115);
                    // force the width to 8px so that everything always draws correctly
                    this.Width = 8;
 
                    // draw the background color for our control image
                    if (hot)
                    {
                        g.FillRectangle(brush_hotColor, new Rectangle(rr.X + 1, rr.Y, 6, 115));
                    }
                    else
                    {
                        g.FillRectangle(brush_backColor, new Rectangle(rr.X + 1, rr.Y, 6, 115));
                    }
 
                    // draw the top & bottom lines for our control image
                    using (Pen pn = new Pen(SystemColors.ControlDark, 1))
                    {
                        g.DrawLine(pn, rr.X + 1, rr.Y, rr.X + rr.Width - 2, rr.Y);
                        g.DrawLine(pn, rr.X + 1, rr.Y + rr.Height, rr.X + rr.Width - 2, rr.Y + rr.Height);
                    }
 
                    if (this.Enabled)
                    {
                        // draw the arrows for our control image
                        // the ArrowPointArray is a point array that defines an arrow shaped polygon
                        g.FillPolygon(brush_controlDarkDark, ArrowPointArray(rr.X + 2, rr.Y + 3));
                        g.FillPolygon(brush_controlDarkDark, ArrowPointArray(rr.X + 2, rr.Y + rr.Height - 9));
                    }
 
                    // draw the dots for our control image using a loop
                    int x = rr.X + 3;
                    int y = rr.Y + 14;
 
                    // Visual Styles added in version 1.1
                    switch (visualStyle)
                    {
                        case VisualStyles.Mozilla:
 
                            for (int i = 0; i < 30; i++)
                            {
                                // light dot
                                g.DrawLine(pen_controlLightLight, x, y + (i * 3), x + 1, y + 1 + (i * 3));
                                // dark dot
                                g.DrawLine(pen_controlDarkDark, x + 1, y + 1 + (i * 3), x + 2, y + 2 + (i * 3));
                                // overdraw the background color as we actually drew 2px diagonal lines, not just dots
                                if (hot)
                                {
                                    g.DrawLine(pen_hotColor, x + 2, y + 1 + (i * 3), x + 2, y + 2 + (i * 3));
                                }
                                else
                                {
                                    g.DrawLine(pen_backColor, x + 2, y + 1 + (i * 3), x + 2, y + 2 + (i * 3));
                                }
                            }
                            break;
 
                        case VisualStyles.DoubleDots:
                            for (int i = 0; i < 30; i++)
                            {
                                // light dot
                                g.DrawRectangle(pen_controlLightLight, x, y + 1 + (i * 3), 1, 1);
                                // dark dot
                                g.DrawRectangle(pen_controlDark, x - 1, y + (i * 3), 1, 1);
                                i++;
                                // light dot
                                g.DrawRectangle(pen_controlLightLight, x + 2, y + 1 + (i * 3), 1, 1);
                                // dark dot
                                g.DrawRectangle(pen_controlDark, x + 1, y + (i * 3), 1, 1);
                            }
                            break;
 
                        case VisualStyles.Win9x:
 
                            g.DrawLine(pen_controlLightLight, x, y, x + 2, y);
                            g.DrawLine(pen_controlLightLight, x, y, x, y + 90);
                            g.DrawLine(pen_controlDark, x + 2, y, x + 2, y + 90);
                            g.DrawLine(pen_controlDark, x, y + 90, x + 2, y + 90);
                            break;
 
                        case VisualStyles.XP:
 
                            for (int i = 0; i < 18; i++)
                            {
                                // light dot
                                g.DrawRectangle(pen_controlLight, x, y + (i * 5), 2, 2);
                                // light light dot
                                g.DrawRectangle(pen_controlLightLight, x + 1, y + 1 + (i * 5), 1, 1);
                                // dark dark dot
                                g.DrawRectangle(pen_controlDarkDark, x, y + (i * 5), 1, 1);
                                // dark fill
                                g.DrawLine(pen_controlDark, x, y + (i * 5), x, y + (i * 5) + 1);
                                g.DrawLine(pen_controlDark, x, y + (i * 5), x + 1, y + (i * 5));
                            }
                            break;
 
                        case VisualStyles.Lines:
 
                            for (int i = 0; i < 44; i++)
                            {
                                g.DrawLine(pen_controlDark, x, y + (i * 2), x + 2, y + (i * 2));
                            }
 
                            break;
                    }
 
                    // Added in version 1.3
                    if (this.borderStyle != System.Windows.Forms.Border3DStyle.Flat)
                    {
                        // Paint the control border
                        ControlPaint.DrawBorder3D(e.Graphics, this.ClientRectangle, this.borderStyle, Border3DSide.Left);
                        ControlPaint.DrawBorder3D(e.Graphics, this.ClientRectangle, this.borderStyle, Border3DSide.Right);
                    }
                }
 
                #endregion
 
                // Horizontal Splitter support added in v1.2

                #region Horizontal Splitter
 
                else if (this.Dock == DockStyle.Top || this.Dock == DockStyle.Bottom)
                {
                    // create a new rectangle in the horizontal center of the splitter for our collapse control button
                    rr = new Rectangle((int)r.X + ((r.Width - 115) / 2), r.Y, 115, 8);
                    // force the height to 8px
                    this.Height = 8;
 
                    // draw the background color for our control image
                    if (hot)
                    {
                        g.FillRectangle(brush_hotColor, new Rectangle(rr.X, rr.Y + 1, 115, 6));
                    }
                    else
                    {
                        g.FillRectangle(brush_backColor, new Rectangle(rr.X, rr.Y + 1, 115, 6));
                    }
 
                    // draw the left & right lines for our control image
                    using (Pen pn = new Pen(SystemColors.ControlDark, 1))
                    {
                        g.DrawLine(pn, rr.X, rr.Y + 1, rr.X, rr.Y + rr.Height - 2);
                        g.DrawLine(pn, rr.X + rr.Width, rr.Y + 1, rr.X + rr.Width, rr.Y + rr.Height - 2);
                    }
                    if (this.Enabled)
                    {
                        // draw the arrows for our control image
                        // the ArrowPointArray is a point array that defines an arrow shaped polygon
                        g.FillPolygon(brush_controlDarkDark, ArrowPointArray(rr.X + 3, rr.Y + 2));
                        g.FillPolygon(brush_controlDarkDark, ArrowPointArray(rr.X + rr.Width - 9, rr.Y + 2));
                    }
 
                    // draw the dots for our control image using a loop
                    int x = rr.X + 14;
                    int y = rr.Y + 3;
 
                    // Visual Styles added in version 1.1
                    switch (visualStyle)
                    {
                        case VisualStyles.Mozilla:
 
                            for (int i = 0; i < 30; i++)
                            {
                                // light dot
                                g.DrawLine(pen_controlLightLight, x + (i * 3), y, x + 1 + (i * 3), y + 1);
                                // dark dot
                                g.DrawLine(pen_controlDarkDark, x + 1 + (i * 3), y + 1, x + 2 + (i * 3), y + 2);
                                // overdraw the background color as we actually drew 2px diagonal lines, not just dots
                                if (hot)
                                {
                                    g.DrawLine(pen_hotColor, x + 1 + (i * 3), y + 2, x + 2 + (i * 3), y + 2);
                                }
                                else
                                {
                                    g.DrawLine(pen_backColor, x + 1 + (i * 3), y + 2, x + 2 + (i * 3), y + 2);
                                }
                            }
                            break;
 
                        case VisualStyles.DoubleDots:
 
                            for (int i = 0; i < 30; i++)
                            {
                                // light dot
                                g.DrawRectangle(pen_controlLightLight, x + 1 + (i * 3), y, 1, 1);
                                // dark dot
                                g.DrawRectangle(pen_controlDark, x + (i * 3), y - 1, 1, 1);
                                i++;
                                // light dot
                                g.DrawRectangle(pen_controlLightLight, x + 1 + (i * 3), y + 2, 1, 1);
                                // dark dot
                                g.DrawRectangle(pen_controlDark, x + (i * 3), y + 1, 1, 1);
                            }
                            break;
 
                        case VisualStyles.Win9x:
 
                            g.DrawLine(pen_controlLightLight, x, y, x, y + 2);
                            g.DrawLine(pen_controlLightLight, x, y, x + 88, y);
                            g.DrawLine(pen_controlDark, x, y + 2, x + 88, y + 2);
                            g.DrawLine(pen_controlDark, x + 88, y, x + 88, y + 2);
                            break;
 
                        case VisualStyles.XP:
 
                            for (int i = 0; i < 18; i++)
                            {
                                // light dot
                                g.DrawRectangle(pen_controlLight, x + (i * 5), y, 2, 2);
                                // light light dot
                                g.DrawRectangle(pen_controlLightLight, x + 1 + (i * 5), y + 1, 1, 1);
                                // dark dark dot
                                g.DrawRectangle(pen_controlDarkDark, x + (i * 5), y, 1, 1);
                                // dark fill
                                g.DrawLine(pen_controlDark, x + (i * 5), y, x + (i * 5) + 1, y);
                                g.DrawLine(pen_controlDark, x + (i * 5), y, x + (i * 5), y + 1);
                            }
                            break;
 
                        case VisualStyles.Lines:
 
                            for (int i = 0; i < 44; i++)
                            {
                                g.DrawLine(pen_controlDark, x + (i * 2), y, x + (i * 2), y + 2);
                            }
 
                            break;
                    }
 
                    // Added in version 1.3
                    if (this.borderStyle != System.Windows.Forms.Border3DStyle.Flat)
                    {
                        // Paint the control border
                        ControlPaint.DrawBorder3D(e.Graphics, this.ClientRectangle, this.borderStyle, Border3DSide.Top);
                        ControlPaint.DrawBorder3D(e.Graphics, this.ClientRectangle, this.borderStyle, Border3DSide.Bottom);
                    }
                }
 
                #endregion
 
                else
                {
                    throw new Exception("The Collapsible Splitter control cannot have the Filled or None Dockstyle property");
                }
 
                // dispose the Graphics objects
                pen_controlLightLight.Dispose();
                pen_controlLight.Dispose();
                pen_controlDark.Dispose();
                pen_backColor.Dispose();
                pen_hotColor.Dispose();
                pen_controlDarkDark.Dispose();
 
                brush_controlDark.Dispose();
                brush_controlDarkDark.Dispose();
                brush_backColor.Dispose();
                brush_hotColor.Dispose();
            }
        }

AnswerRe: memory management bugmembertr02178 Feb '11 - 17:58 
Very usefull, and I want to use it in my project.
 
To be fankly, it do exists a memory-leak problem in the OnPaint method. I also encountered such kind of problem before. An experienced programmer told me that all graphic object(Pen, Brush, Font and what not) need to be disposed.
GeneralRe: memory management bugmemberMember 143012617 Aug '11 - 7:12 
This is only true if you create the Graphics object using Graphics.FromXxxxx()
GeneralNew implementation for SplitterContaintermembermarioz814 Sep '07 - 8:05 
Hi, I have been tryied to implement a similar component when I lock your. So I get some methods from our implementation but inheriting from SplitterContainer. I want to know if I can do a article discribing the changes that I made based on your component a submite the source code for other developers.
 
Mário Santos, Brazil.
GeneralRe: New implementation for SplitterContaintermemberFurty14 Sep '07 - 13:10 
So long as you link back to this article, go for it Mário.
GeneralAnimationDelay does nothingmemberjbshaler11 Jul '07 - 4:36 
Thanks a lot for this control! It's really nice (although it seems like it should still work like a normal splitter when the control to collapse is not set -- I wanted it originally just for the improved look).
 
One thing: the Interval property of the animation timer is only set in the constructor, so setting the AnimationDelay property does nothing. Add the following line in the set accessor of AnimationDelay:
 
animationTimer.Interval = value;
 
Still, it doesn't change much to go shorter than the default of 20 due to the timer resolution, and I doubt anyone is going to want to make it longer (more choppy motion).
 

GeneralRe: AnimationDelay does nothingmemberorientalCSharp20 Jun '10 - 21:49 
It should set "this.animationTimer.Interval = value;" in the Property of AnimationDelay
 
Thus it looks like follows:
 
[Bindable(true), Category("Collapsing Options"), DefaultValue("20"),
Description("The delay in millisenconds between animation steps")]
public int AnimationDelay
{
get { return this.animationDelay; }
set { this.animationDelay = value; this.animationTimer.Interval = value; }
}
GeneralNEWBEmemberLonnie117 Nov '06 - 9:04 
Can I use a button to do open/close the panels or do I have to use the toolbar? If I can use the button, how would I code it? This is my first time using c and I need all the help I can get.
 
Thanks
GeneralAccess Violation ExceptionmemberLouis-Philippe Carignan2 Nov '06 - 5:01 
Hi,
 
We have integrated the collapsible splitter into our application. It worked fine under .NET 1.1 but we now have issues with it under 2.0. The problem seems random as we can't find a pattern to reproduce it. It even happens when the form with the splitter in it is minimized. We sometimes get the following error message when the splitter paints itself.
 
System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at System.Drawing.SafeNativeMethods.Gdip.GdipDrawLineI(HandleRef graphics, HandleRef pen, Int32 x1, Int32 y1, Int32 x2, Int32 y2)
at System.Drawing.Graphics.DrawLine(Pen pen, Int32 x1, Int32 y1, Int32 x2, Int32 y2)
at CollapsibleSplitter.OnPaint(PaintEventArgs e) in C:\DEV\APTS\NJFLib.Controls\NJFLib.Controls.CollapsibleSplitter.cs:line 601
at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer, Boolean disposeEventArgs)
at System.Windows.Forms.Control.WmPaint(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run()
 
Any ideas on why this happen?
GeneralNice one dude !!memberscanner77716 Sep '06 - 21:48 
Big Grin | :-D
GeneralA problem used in MDI applicationmembergrrrrr14 Dec '05 - 13:32 
For example,I have a treeview docked in the left which is the hide control of the Collapsible Splitter control "CollapsibleSplitter1". Then it works well. But now I want to hide the ChildForm, and expand the threeview. How should I do?
GeneralI added an event &quot;StateChanged&quot; into the controlmemberWayne Wood13 Sep '05 - 4:28 
you know, sometimes we need to update other UI elements when the splitter folded or unfolded, but i found no event notification was raised when the state toggled in this control. then i added one by myself, which is very simple.
 
i'm fresh here, so i dont know how to post code or upload attachment package Frown | :( who can help me to post my modification? thanks
GeneralMemory problemmemberkanaan8118 Jul '05 - 4:09 
Hi
I think you have a problem in your code, because in the demo exe, every time we use your splitter in the exe the memory usage increase(you can monitor the memory usage with windows task manager) OMG | :OMG:
I think your allocate variables without deallocation..Roll eyes | :rolleyes:
 
kanaan

GeneralTabPagesmemberJon Lea17 Mar '05 - 11:21 
Furty - nice control and I have things working pretty much the way I want except that when I collapse your splitter to the right edge of a tabPage (this splitter hides panel4 docked to the right side) I no longer can see the splitter. I have a collapsible splitter on the left side (hidding panel1 docked to the left) and a splitter on the top (this hides panel2) and they work fine.
 
Any idea why the right side is giving me problems?
 
The app is a Form with a tabSheet and two tab pages. The second tab page is where the collapsible splitters are and the four panes:
 
panel2
panel1 VCS HCS VCS panel4
panel3
 
Thanks.
 
Jon.
GeneralRe: TabPagesmemberFurty17 Mar '05 - 16:13 
Hi Jon,
 
It sounds like you've got the second VCS as a child of Panel4, rather than a child of the TabPage itself. Failing this, it could be a z-order issue.
 
As noted in this[^] thread, all such issues usually end up being a simple heirarchy problem.
GeneralWorks fine on Form, buggy on ControlsussLee Grissom3 Mar '05 - 8:08 
When we put the splitter on a form, it works as expected. However, when we put it on a custom control (or standard panel), it has problems. It correctly draws itself, and correctly hides/shows the "controlToHide". However, the location of the splitter does not move. When we place everything on a Panel, it moves, but the "dark gray" outline of the "old" position remains. Our guess is that there is a bunch of extra processing that occurs behind the scenes on the Form vs. a control. Any ideas on how we might get this to work correctly? Thanks.
GeneralRe: Works fine on Form, buggy on ControlmemberPunCha13 Feb '07 - 22:52 
Yeah! I met the same problem:
 
Please allow me to use the term "Shadow" to describe the stuff which I really didn't know how to name it. The term "Shadow" is: When you press the splitter( don't release you mouse ) or drag the splitter, you can see a "Shadow" which helps to identify the position of the splitter.
 
----------------------------------------------
OK, here is the issue:
1, I set the UseAnimation to "False", Mozila style and run the application.
2, When I click the splitter, everything is OK except the "Shadow" still left.
3, And I replace your splitter with .Net 2.0's. The sistuation still happens. So I think it's Windows's fault.
 
Release PunCha's Power!
GeneralRe: Works fine on Form, buggy on Controlmemberaldo hexosa15 Feb '09 - 16:26 
I think it's splitter's bug. i also met this shadow when using splitter with user control in panel. anyone please help D'Oh! | :doh:
Questioncollapsible splitter button - able to drag?memberJohnny O23 Feb '05 - 11:04 
It appears you can't drag/resize the splitter by attempting to "grab" the splitter button. The button only allows clicking to hide a control. It would be nice to allow re-sizing as well but didn't find a way.
AnswerRe: collapsible splitter button - able to drag?memberPunCha13 Feb '07 - 22:40 
You can made the following changes to the member function OnMouseDown:
protected override void OnMouseDown(MouseEventArgs e)
{
    // if the hider control isn't hot, let the base resize action occur
    if (this.controlToHide != null)
    {
        if (/*!this.hot &&*/ this.controlToHide.Visible)
        {
            base.OnMouseDown(e);
        }
    }
}

 
Release PunCha's Power!
GeneralOffscreen Drawing...memberTJoe23 Dec '04 - 0:56 
I added offscreen drawing to OnPaint. At times I could see the individual dots being drawn Smile | :)
 
Other than that great control and thanks!
 
t
 
relavent code
 

// OnPaint is now an override rather than an event in version 1.1
protected override void OnPaint(PaintEventArgs e)
{
// create a Graphics object
Graphics g = e.Graphics;

//create our offscreen bitmap
Bitmap b = new Bitmap(ClientRectangle.Width,
ClientRectangle.Height);
Graphics bg = Graphics.FromImage(b);
bg.Clear(this.BackColor);

// find the rectangle for the splitter and paint it
Rectangle r = this.ClientRectangle; // fixed in version 1.1
// g.FillRectangle(new SolidBrush(this.BackColor), r);
 
#region Vertical Splitter
// Check the docking style and create the control rectangle accordingly
if(this.Dock == DockStyle.Left || this.Dock == DockStyle.Right)
{
// create a new rectangle in the vertical center of the splitter for our collapse control button
rr = new Rectangle(r.X, (int)r.Y + ((r.Height - 115)/2), 8, 115);
// force the width to 8px so that everything always draws correctly
this.Width = 8;
 
// draw the background color for our control image
if(hot)
{
bg.FillRectangle(new SolidBrush(hotColor), new Rectangle(rr.X + 1, rr.Y, 6, 115));
}
else
{
bg.FillRectangle(new SolidBrush(this.BackColor), new Rectangle(rr.X + 1, rr.Y, 6, 115));
}
 
// draw the top & bottom lines for our control image
bg.DrawLine(new Pen(SystemColors.ControlDark, 1), rr.X + 1, rr.Y, rr.X + rr.Width - 2, rr.Y);
bg.DrawLine(new Pen(SystemColors.ControlDark, 1), rr.X + 1, rr.Y + rr.Height, rr.X + rr.Width - 2, rr.Y + rr.Height);
 
if(this.Enabled)
{
// draw the arrows for our control image
// the ArrowPointArray is a point array that defines an arrow shaped polygon
bg.FillPolygon(new SolidBrush(SystemColors.ControlDarkDark), ArrowPointArray(rr.X + 2, rr.Y + 3));
bg.FillPolygon(new SolidBrush(SystemColors.ControlDarkDark), ArrowPointArray(rr.X + 2, rr.Y + rr.Height - 9));
}
 
// draw the dots for our control image using a loop
int x = rr.X + 3;
int y = rr.Y + 14;
 
// Visual Styles added in version 1.1
switch(visualStyle)
{
case VisualStyles.Mozilla:
 
for(int i=0; i < 30; i++)
{
// light dot
bg.DrawLine(new Pen(SystemColors.ControlLightLight), x, y + (i*3), x+1, y + 1 + (i*3));
// dark dot
bg.DrawLine(new Pen(SystemColors.ControlDarkDark), x+1, y + 1 + (i*3), x+2, y + 2 + (i*3));
// overdraw the background color as we actually drew 2px diagonal lines, not just dots
if(hot)
{
bg.DrawLine(new Pen(hotColor), x+2, y + 1 + (i*3), x+2, y + 2 + (i*3));
}
else
{
bg.DrawLine(new Pen(this.BackColor), x+2, y + 1 + (i*3), x+2, y + 2 + (i*3));
}
}
break;
 
case VisualStyles.DoubleDots:
for(int i=0; i < 30; i++)
{
// light dot
bg.DrawRectangle(new Pen(SystemColors.ControlLightLight), x, y + 1 + (i*3), 1, 1 );
// dark dot
bg.DrawRectangle(new Pen(SystemColors.ControlDark), x - 1, y +(i*3), 1, 1 );
i++;
// light dot
bg.DrawRectangle(new Pen(SystemColors.ControlLightLight), x + 2, y + 1 + (i*3), 1, 1 );
// dark dot
bg.DrawRectangle(new Pen(SystemColors.ControlDark), x + 1, y + (i*3), 1, 1 );
}
break;
 
case VisualStyles.Win9x:
 
bg.DrawLine(new Pen(SystemColors.ControlLightLight), x, y, x + 2, y);
bg.DrawLine(new Pen(SystemColors.ControlLightLight), x, y, x,y + 90);
bg.DrawLine(new Pen(SystemColors.ControlDark), x + 2, y, x + 2, y + 90);
bg.DrawLine(new Pen(SystemColors.ControlDark), x, y + 90, x + 2, y + 90);
break;
 
case VisualStyles.XP:
 
for(int i=0; i < 18; i++)
{
// light dot
bg.DrawRectangle(new Pen(SystemColors.ControlLight), x, y + (i*5), 2, 2 );
// light light dot
bg.DrawRectangle(new Pen(SystemColors.ControlLightLight), x + 1, y + 1 + (i*5), 1, 1 );
// dark dark dot
bg.DrawRectangle(new Pen(SystemColors.ControlDarkDark), x, y +(i*5), 1, 1 );
// dark fill
bg.DrawLine(new Pen(SystemColors.ControlDark), x, y + (i*5), x, y + (i*5) + 1);
bg.DrawLine(new Pen(SystemColors.ControlDark), x, y + (i*5), x + 1, y + (i*5));
}
break;
 
case VisualStyles.Lines:
 
for(int i=0; i < 44; i++)
{
bg.DrawLine(new Pen(SystemColors.ControlDark), x, y + (i*2), x + 2, y + (i*2));
}
 
break;
}
 
// Added in version 1.3
if(this.borderStyle != System.Windows.Forms.Border3DStyle.Flat)
{
// Paint the control border
ControlPaint.DrawBorder3D(bg, this.ClientRectangle, this.borderStyle, Border3DSide.Left);
ControlPaint.DrawBorder3D(bg, this.ClientRectangle, this.borderStyle, Border3DSide.Right);
}
}
 
#endregion
 
// Horizontal Splitter support added in v1.2
 
#region Horizontal Splitter
 
else if (this.Dock == DockStyle.Top || this.Dock == DockStyle.Bottom)
{
// create a new rectangle in the horizontal center of the splitter for our collapse control button
rr = new Rectangle((int)r.X + ((r.Width - 115)/2), r.Y, 115, 8);
// force the height to 8px
this.Height = 8;
 
// draw the background color for our control image
if(hot)
{
bg.FillRectangle(new SolidBrush(hotColor), new Rectangle(rr.X, rr.Y + 1, 115, 6));
}
else
{
bg.FillRectangle(new SolidBrush(this.BackColor), new Rectangle(rr.X, rr.Y + 1, 115, 6));
}
 
// draw the left & right lines for our control image
bg.DrawLine(new Pen(SystemColors.ControlDark, 1), rr.X, rr.Y + 1, rr.X, rr.Y + rr.Height - 2);
bg.DrawLine(new Pen(SystemColors.ControlDark, 1), rr.X + rr.Width, rr.Y + 1, rr.X + rr.Width, rr.Y + rr.Height - 2);
 
if(this.Enabled)
{
// draw the arrows for our control image
// the ArrowPointArray is a point array that defines an arrow shaped polygon
bg.FillPolygon(new SolidBrush(SystemColors.ControlDarkDark), ArrowPointArray(rr.X + 3, rr.Y + 2));
bg.FillPolygon(new SolidBrush(SystemColors.ControlDarkDark), ArrowPointArray(rr.X + rr.Width - 9, rr.Y + 2));
}
 
// draw the dots for our control image using a loop
int x = rr.X + 14;
int y = rr.Y + 3;
 
// Visual Styles added in version 1.1
switch(visualStyle)
{
case VisualStyles.Mozilla:
 
for(int i=0; i < 30; i++)
{
// light dot
bg.DrawLine(new Pen(SystemColors.ControlLightLight), x + (i*3), y, x + 1 + (i*3), y + 1);
// dark dot
bg.DrawLine(new Pen(SystemColors.ControlDarkDark), x + 1 + (i*3), y + 1, x + 2 + (i*3), y + 2);
// overdraw the background color as we actually drew 2px diagonal lines, not just dots
if(hot)
{
bg.DrawLine(new Pen(hotColor), x + 1 + (i*3), y + 2, x + 2 + (i*3), y + 2);
}
else
{
bg.DrawLine(new Pen(this.BackColor), x + 1 + (i*3), y + 2, x + 2 + (i*3), y + 2);
}
}
break;
 
case VisualStyles.DoubleDots:
 
for(int i=0; i < 30; i++)
{
// light dot
bg.DrawRectangle(new Pen(SystemColors.ControlLightLight), x + 1 + (i*3), y, 1, 1 );
// dark dot
bg.DrawRectangle(new Pen(SystemColors.ControlDark), x + (i*3), y - 1, 1, 1 );
i++;
// light dot
bg.DrawRectangle(new Pen(SystemColors.ControlLightLight), x + 1 + (i*3), y + 2, 1, 1 );
// dark dot
bg.DrawRectangle(new Pen(SystemColors.ControlDark), x + (i*3), y + 1, 1, 1 );
}
break;
 
case VisualStyles.Win9x:
 
bg.DrawLine(new Pen(SystemColors.ControlLightLight), x, y, x, y + 2);
bg.DrawLine(new Pen(SystemColors.ControlLightLight), x, y, x + 88, y);
bg.DrawLine(new Pen(SystemColors.ControlDark), x, y + 2, x + 88, y + 2);
bg.DrawLine(new Pen(SystemColors.ControlDark), x + 88, y, x + 88, y + 2);
break;
 
case VisualStyles.XP:
 
for(int i=0; i < 18; i++)
{
// light dot
bg.DrawRectangle(new Pen(SystemColors.ControlLight), x + (i*5), y, 2, 2 );
// light light dot
bg.DrawRectangle(new Pen(SystemColors.ControlLightLight), x + 1 + (i*5), y + 1, 1, 1 );
// dark dark dot
bg.DrawRectangle(new Pen(SystemColors.ControlDarkDark), x +(i*5), y, 1, 1 );
// dark fill
bg.DrawLine(new Pen(SystemColors.ControlDark), x + (i*5), y, x + (i*5) + 1, y);
bg.DrawLine(new Pen(SystemColors.ControlDark), x + (i*5), y, x + (i*5), y + 1);
}
break;
 
case VisualStyles.Lines:
 
for(int i=0; i < 44; i++)
{
bg.DrawLine(new Pen(SystemColors.ControlDark), x + (i*2), y, x + (i*2), y + 2);
}
 
break;
}
 
// Added in version 1.3
if(this.borderStyle != System.Windows.Forms.Border3DStyle.Flat)
{
// Paint the control border
ControlPaint.DrawBorder3D(bg, this.ClientRectangle, this.borderStyle, Border3DSide.Top);
ControlPaint.DrawBorder3D(bg, this.ClientRectangle, this.borderStyle, Border3DSide.Bottom);
}
}
 
#endregion
 
else
{
throw new Exception("The Collapsible Splitter control cannot have the Filled or None Dockstyle property");
}

 
//push our bitmap forward to the screen
g.DrawImage(b, 0, 0);
 
bg.Dispose();
b.Dispose();
 
// dispose the Graphics object
g.Dispose();
}

Questionhow to work with itsussAnonymous16 Dec '04 - 14:06 
I have placed it on my form but I don't know how to expand it
AnswerRe: how to work with itmemberFurty16 Dec '04 - 14:15 
"It" itself doesn't collapse, rather it collapses the control you've specified in the ControlToHide property. In all other respects it works the same as the standard Splitter control. For more info read the article or the comments in the code.
GeneralRe: how to work with itsussAnonymous17 Dec '04 - 6:03 
hanks for your reply,I'm really enjoying it but how come yuo didn't post the sample with it.I have got 2 questions:
 
1)how can I put the spliter on the other side of control like what you have done in your demo?Mine is always stuck to the edge of the form.
 
2)How can I adjust the height of control.
 
That's awesome man.

GeneralCollapsible Splitter in Combination with DockPanelSuitememberrascreek25 Oct '04 - 3:25 
Hi there!
I am using the collapsible splitter in combination with Weifen Lou´s DockPanelSuite.
When I use the collapsibleSplitter with normal windows forms panels everything works perfect. As soon as I use a DockPanel instead of the normal Panel it appears that the splitter control is sometimes drawn, sometimes not drawn or sometimes partly drawn.
Cause that phenomenon is only happening in combination with dockpanelsuite I guess it´s a problem of the dockpanelsuite.
 
Does anybody have a clue what the problem is about and do you know how to solve it or at least give me a hint?
 
thanks in advance,
 
rascreek

GeneralRe: Collapsible Splitter in Combination with DockPanelSuitememberrobdogg117 Nov '04 - 8:22 
I have the same problem. I am not using the DockPanelSuite, however, my form is very heavily paneled. Have you found a solution since your post?
GeneralRe: Collapsible Splitter in Combination with DockPanelSuitememberrobdogg117 Nov '04 - 9:14 
I think the Panel controls just ignore the CollapsibleSplitter. I've cooked up a sample project that shows this behaviour. I've posted it at
 
http://www.vbrad.com/downloads/furty.zip
 
for the author to take a look at.
GeneralRe: Collapsible Splitter in Combination with DockPanelSuitememberFurty17 Nov '04 - 13:26 
Please check the control heirarchy in your project.
 
The CollapsibleSplitter is the same as the base Splitter control in the fact that it will only have an effect on sibling controls - it cannot have any effect on controls that are higher up the heirarchy than itself, and will not have a direct effect on controls lower in the heirarchy.
 
Unfortunately I get emails every week from people who make the CollapsibleSplitter a child of a panel/control and then wonder why it doesn't hide it.D'Oh! | :doh:
 
If in doubt, replace the CollapsibleSplitter with a standard Splitter and test..
GeneralRe: Collapsible Splitter in Combination with DockPanelSuitememberrobdogg117 Nov '04 - 17:59 
Furty, the controls are definetely in the proper hierarchy. If you don't believe me, check out the sample project, I posted 2 messages above.
 
I believe, when the entire set of panels is in a parent panel, the inner panels do ignore the CollapsibleSplitter, but don't ignore the regular Splitter control.
 
I fixed the issue in my app by removing as many panels as I possibly could, but if you'll check the sample project, you'll see that I am right.
 
Btw, thanks again for a fantastic component.

GeneralRe: Collapsible Splitter in Combination with DockPanelSuitememberFurty17 Nov '04 - 19:05 
Hi robdogg,
 
I've had a look at your sample app, and the problem is definately related to heirarchy, or more specifically, the z-order within the heirarchy.
 
In order to make the sample application behave the way you want, you need to manipulate the z-order so it looks like this:
 
Form1
-panelPage
--panelNameAndBrowser
---browser
---panel1
----checkBox1
----radioButton1
--collapsibleSplitter1
--panelCalendar
 
Use the Send to Back/Send to Front from the context menu to get it in the right order, and it will work as expected.
 
Hope this helps.
GeneralRe: Collapsible Splitter in Combination with DockPanelSuitememberrobdogg118 Nov '04 - 8:09 
Furty,
 
Thank you very much. Your comments were right on the money. I had no idea that the order of the controls being added via the .Controls.Add made a difference. Kind of odd. I would thing that zorder would be manipulated via perhaps a ZOrder property, but it doesn't exist.
GeneralRe: Collapsible Splitter in Combination with DockPanelSuitememberrascreek22 Nov '04 - 2:47 
hey guys!
i just came back from my well-earned holidays and see the solution to my problem has been found!
thanks a lot furty and also rob for the example file!
 
I like it when my first working day starts with good news! Smile | :)
 
greets,
 
ras
GeneralSplitter with tabControlsmemberRoadRage26 Sep '04 - 9:57 
I can't seem to get this to work with a tabConrol. It works great with the other controls I have tried. I get an error in designed view saying that only tabPages can be added to a tabControl.
 
I can make it work but it doesn't look right, it docks on the left side of the tabControl with the arrows facing the wrong way.
 
Any ideas?
 
Thanks
 

GeneralRe: Splitter with tabControlsmemberFurty1 Oct '04 - 14:55 
The error message you're seeing is correct - a blank TabControl will only accept a TabPage instance as a child. What is it you want to collapse? If it's the TabControl itself, you should be adding the CollapsibleSplitter to the control that's parent to the TabControl, not the TabControl itself.
 
For example, if your TabControl's parent is a form, and the CollpasibleSplitter to the Form, if it's a panel add the splitter to the panel, etc.
 
Hope this helps.
GeneralMozillasussDeeWorld9 Sep '04 - 19:23 
Hey...cool deal here. But why do you say "based on Mozilla web browser".
 
This idea has been around a lot longer than the Mozilla people and even before the Netscape type's decided to snipe some school code and start a company.
 
hmmm...might have actually been one of those boys in Redmond that first came out with the idea (as I remember it anyway) Smile | :)

GeneralRe: MozillamemberFurty9 Sep '04 - 21:33 
DeeWorld wrote:
Hey...cool deal here. But why do you say "based on Mozilla web browser".
 
Quite simply because that's exactly what I modelled it from Wink | ;) -The size, the behaviour and the visual style all come from Mozilla's implementation.
 
You're right in the fact that this style of control has been in many other products, most notably probably being Adobe Acrobat, but I'd still think that Mozilla is the application that truly popularised it.
 
DeeWorld wrote:
hmmm...might have actually been one of those boys in Redmond that first came out with the idea (as I remember it anyway)
 
Old enemies die hard eh? Poke tongue | ;-P
 
The blogless coder
QuestionHow to make the grippie shorter?memberrobdogg126 Aug '04 - 11:48 
How can I make the grippie shorter? Any ideas?
AnswerRe: How to make the grippie shorter?memberFurty9 Sep '04 - 21:41 
Unfortunately in this (old) release the height of the button was hard coded in many places - it can be done, but it's going to take a few compiles to get it working right.
 
Much better would be for me to actually get around to posting V2 of this control which has been done for a few months now Frown | :(
 
The blogless coder
GeneralRe: How to make the grippie shorter?memberrobdogg110 Sep '04 - 9:07 
>>Much better would be for me to actually get around to posting V2 of this control which has been done for a few months now
<<
 
Then by all means, post it.
Also, if you aren't planning to post it in the near future, is it possible to receive it from you privately?
 
Thanks
GeneralRe: How to make the grippie shorter?memberFurty10 Sep '04 - 17:50 
robdogg1 wrote:
Then by all means, post it.
 
As sson as I figure out how to make more hours in the day, I will Smile | :)
 
robdogg1 wrote:
Also, if you aren't planning to post it in the near future, is it possible to receive it from you privately?
 
The updated control is now part of a much bigger library - my intention was to prepare the entire library as an article, rather than just the updated splitter code.
 
The blogless coder
GeneralRe: How to make the grippie shorter?memberFurty1 Oct '04 - 15:02 
The next version of the CollapsibleSplitter control is now part of a much larger UI library, and has many dependencies on other classes. For this reason I may not be releasing it as a standalone control.
 
I have posted a preview of the upcoming library to my (new) website, here[^]
 
At this stage I am still undecided on how to release this new library. Ideas would be appreciated!
GeneralDude...memberrobdogg116 Aug '04 - 14:33 
...you are awesome! This is *exactly* what I was looking for. Animations are just icing on the cake. I was thinking of going with docked windows, but for beginner users the idea of splitters is easier to understand (try and dock a window in vs.net), plus they've already seen it in Acrobat6.
 
Thanks.
GeneralAutomatically detection of controlToHidememberdon!marco21 Jul '04 - 19:39 
Hi there,
 
thank you very much for this good job. I have a suggestion to make this very usefull control a little bit more usefull Laugh | :laugh:
I have been using my own Splitter control that i had written after i had seen the Mozillas splitter. In fact it was not so smart like your control (so i decided to drop it and use yours), but had one advantage: like the original splitter, it detects it's controlToHide property automatically. The following function i found, at least, by reengineering and modifying the original splitters routine:
 
GetControlToHide()
{
Control parentControl;
DockStyle ownDockStyle;
int parentControlIndex;
DockStyle parentControlDockStyle;
 
parentControl = this.Parent;
if (parentControl == null) return null;
ownDockStyle = this.Dock;
parentControlIndex = 0;
while (parentControlIndex < parentControl.Controls.Count)
{
this.controlToHide = parentControl.Controls[parentControlIndex];
if (this.controlToHide != this)
{
parentControlDockStyle = ownDockStyle;
switch ((int)parentControlDockStyle - 1)
{
case 0:
if (this.controlToHide.Bottom != this.Top) break;
return this.controlToHide;
case 1:
if (this.controlToHide.Top != this.Bottom) break;
return this.controlToHide;
case 2:
if (this.controlToHide.Right != this.Left) break;
return this.controlToHide;
case 3:
if (this.controlToHide.Left == this.Right) return this.controlToHide;
break;
}
}
parentControlIndex++;
}
return null;
}
 

After using that, and a little workaround to replace the orignial controlToHide property, your splitter works perfectly Cool | :cool:
GeneralIsCollapsed property issue with Animationmembercsager2 Jun '04 - 8:30 
The control works great and is exactly what I'm looking for, but I have hit what I think to be a bug.
 
Repro:
1) Add Control to form and set the ControlToHide property
2) Set UseAnimations = True
3) Add Code to click event in VB.net forms application:

msgbox("IsCollapsed = " & cstr(CollapsibleSplitter1.IsCollapsed))
 
4) Run Application and click on the CollapsibleSplitter control to collapse or expand.
 
Result = Textbox returns "IsCollapsed = False"
 
Additional notes:
a)If I turn the animations off...it works as expected.
b)Adding doevents() before calling textbox has no effect
c)Adding a delay doesn't seem to help either.
 
Thanks,
 
- CSager

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 27 Aug 2003
Article Copyright 2002 by Furty
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid