Search code examples
c#visual-studiowinformsmaterial-designvisualdesigner

How to design or somehow get a custom WindowBar and grip


Like in Visual Studio, let's say the ToolBox, it has a blue draggable WindowBar like this:

ToolBox

or like this:

VerticalGrip

Is there a DLL to get one, or an easy way to make it?


Solution

  • To render some control to look like some system element, like a a grip, you can use a suitable VisualStyleRenderer

    As you can see there is a huge number! - Here is how you would add a VisualStyleElement.Rebar.Gripper to a Panel:

    private void panel1_Paint(object sender, PaintEventArgs e)
    {
        // any other drawing before..
        DrawVisualStyleElementRebarGripper1(e);
    }
    

    Here is a typical implementation of the method to call:

    public void DrawVisualStyleElementRebarGripper1(PaintEventArgs e)
    {
        if (VisualStyleRenderer.IsElementDefined(
            VisualStyleElement.Rebar.Gripper.Normal))
        {
            VisualStyleRenderer renderer =
                    new VisualStyleRenderer(VisualStyleElement.Rebar.GripperVertical.Normal);
            Rectangle rectangle1 = new Rectangle(0, 0, 
                                                20,  (int)e.Graphics.VisibleClipBounds.Height);
            renderer.DrawBackground(e.Graphics, rectangle1);
        }
        //else
        //    e.Graphics.DrawString("This element is not defined in the current visual style.",
        //            this.Font, Brushes.Black, new Point(10, 10));
    }
    

    Result:

    enter image description here

    Make sure to call the rendering method after any other paint action so it won't get painted over

    Note that are two of them: GripperVertical and Gripper; on my system (W10) they look the same but on other systems they may not!

    If you actually want a custom grip style you could paint it with a suitable hatchpattern brush; that would look the same across all systems, which may be what you want. But it would also mean that it will not always integrate with the rest of windows; this solution will always use the style of the current machine.

    Update:

    If you want to allow dragging the control you can use Vanethrane's answer for the basic functionality. For better UX also make sure to consider these points:

    • Use all three events, MouseDown, -Move and -Up.
    • Change the Cursor from Default to Hand and SizeAll
    • Test if you are in the grip area
    • Before moving bring the control to the top of the z-order with BringToFront to avoid passing under any other control
    • In the MouseDown store the current position twice; once for moving and once for restoring in case the final location is invalid
    • often you want to use a grid to control the final position and...
    • ..often you want to have the control align itself 'magnetically' with the closest neighbour. Use MouseUp to change the final position accordingly..

    I suggest to bundle all the functionality into a DraggableControl class.