Border Container - A Panel on Steroids
With the changes to the BorderControl I wrote two years ago, the once slim and trim replacement for the WinForms.Panel control has grown large, fat, and heavy! It was a small price to pay to improve the UI for the applications I've been working on, and while the control has grown in size and complexity, the machines using my controls have also grown in power and ability... so it was a wash as far as I was concerned.
That having been said, you could easily take this new control and remove from it everything you didn't require and wind up with a fairly small DLL.
While you can dynamically adjust the height of the Header within the BorderContainer (BC), the three buttons: Close, Collapse, and Activation, are all fixed in height and width, so if you planned on a Header with a height of 12 pixels and you wanted to use one or more of the management buttons, you'll definitely want to change the images within the ImageList as well as the CONST s that are used for ButtonHeight and ButtonWidth as well.
|
|
| |
| Along with the BorderContainer (a replacement for the Panel control), you also get in the DLL, a BorderForm which is a replacement for Windows.Forms.Form . It has all of the same properties as BorderContainer minus the Collapse capabilities. There is also a property that sets the opacity of the form while being dragged.
The image on the left shows a sample BorderForm .
|
The image on the right shows that same BorderForm being dragged with a DragOpacity of 0.5. |
BorderForm - Being dragged
|
|
| |
| Author's note: The Color Selector control used as a replacement for .NET's color property editor is included in BorderContainer.dll. It's a dialog box, but as you can see from the demo BorderContainer shown here, you can also use the individual parts: ColorBox and VerticalColorSlider .
|
What's New?
A graphical 'collapse' button has replaced the old-style push-pins. The image for this button changes based on where the BorderContainer
is docked. There is an ImageList
that holds normal, mouse-over, and mouse-down images for Top, Left, Right, and Bottom collapsing as well as the Activation and Close buttons. They are 17x19 32 bit PNGs, but changing them would be as easy as replacing the corresponding images within that ImageList
, making sure you change the sizes appropriately - then changing the two constants: BUTTON_HEIGHT
and BUTTON_WIDTH
to match your new image size.
ButtonOffset
- This is a property that allows you to adjust how close to the right-edge of the BC you want your buttons to line up with.ButtonGap
- a property that allows you to adjust the number of pixels in between each button.
A 3-color gradient header is now available along with the ability to adjust where the center color fades in:
BackgroundColorBegin
- The starting color of your gradient.BackgroundColorCenter
- The middle color of the gradient.BackgroundColorEnd
- The final color of the gradient. This is also the solid color used to fill-in the Header if you select no gradient, as well as the color used to fill-in the side panels if you enter an InnerBorderWidth
> 0.
Here are some of the properties that have been added:
AutoCollapse
: If True
, the BorderContainer
(BC) will automatically collapse when the user double-clicks the header.AutoRefresh
: If True
, the BC will refresh itself automatically whenever UI properties are changed. You can turn this to False
if you're going to set a large number of properties at run-time, then refresh the entire control when your property changes have been completed.AllowResize
: If True
, the user can resize the control at run-time without having to place a Splitter
control next to the BC.InnerBorderWidth
: A property that will display a border along the inside of the BC - the ClientRectangle
is automatically adjusted to prevent controls added to the BC from drawing over the top of this inner border.RoundedCorners
: When set to True
will draw the header with rounded edges, the size of which is adjusted by setting the RoundSize
property.
Using the Code
Drop the DLL into your Libraries folder (or wherever you put your own custom-controls), then add it to the VS IDE toolbar. Once added to the Toolbar, you can use the BC just like a Panel
.
Property Details
BorderContainer
has the following properties:
BorderDetails | | This is an expandable property that contains the bulk of the UI settings. |
| |
BorderColor | | The color of your border | BorderLines | | Expandable property holding all of the border settings | | |
InnerBorder | | If True , will draw a single-pixel border around the inside of the client area | InnerPanelShowAll | | If True , will set all InnerPanel properties to True | InnerPanelShowBottom | | Displays the Bottom Inner Panel | InnerPanelShowLeft | | Displays the Left Inner Panel | InnerPanelShowRight | | Displays the Right Inner Panel | InnerPanelShowTop | | Displays the Top Inner Panel but only if DisplayHeader has been set to False . | ShowAllOutLines | | If True , will set all OutLine properties to True | ShowBottomOutLine | | Shows the Bottom Outline | ShowLeftOutLine | | Shows the Left Outline | ShowRightOutLine | | Shows the Right Outline | ShowTopOutLine | | Shows the Top Outline |
| | | | DisplayHeader | | If True , a header will be displayed at the top of the BorderContainer | HeaderDetails | | Expandable property - all of the details are listed below in this document | InnerBorderWidth | | Establishes the width in pixels of the Inner Border panels; valid settings range from 0 (no border) to 10 (very wide) |
|
| | |
AllowResize | | If True , this will allow the user to resize the non-docked edge(s) of the BC; if the BC is docked, only the movable size of the BC can be dragged for resizing |
| | |
AutoCollapse | | If True , the BC will collapse when the user double-clicks the Header |
| | |
AutoRefresh | | If True , the BC will repaint whenever any UI properties are adjusted during run time; if you have a large number of UI properties to change, you might want to set this to False - make your changes, then reset this value to True so the painting only occurs once |
| | |
CollapsePanel | | This is a built-in Panel control that appears if ShowCollapsePanel = True and the BC has been collapsed; you can set all standard panel properties at design-time, but you'll have to add any additional controls to this panel at run-time |
| | |
CurrentState | | This identifies how the Container will be displayed when the form is opened; 'open' is the default, but you can have the control collapsed at start-up |
| | |
HeaderImage | | An icon you can place inside the Header |
HeaderImageAlignment | | Horizontal placement of the icon |
BorderDetails.HeaderDetails
is an expandable property that handles all Header-specific UI elements, and has the following sub-properties:
ActivationMenu | | This built-in ContextMenuStrip can be edited from within the BorderContainer properties window or at run-time. To add menu items to the strip, expand the ActivationMenu property, scroll down to 'Items', and click on the collection editor. All ToolStripItem types are supported and are added as controls to your form, just as if you had created them by adding your own MenuStrip ... so, if you want to trap the SelectedIndexChanged event of a MenuStripComboItem - just look for the control in the 'Class Name' drop down in the VS IDE. |
AntiAliasText | | If True , the text displayed in the Header will be anti-aliased. |
BackgroundColorBegin | | The starting color for the gradient used to fill the Header. |
BackgroundColorCenter | | The middle color for the gradient. |
BackgroundColorEnd | | Has several purposes: first, its the final color in the gradient. It is also the color used to fill the inner panels if InnerPanelWidth > 0, and it is the solid color used to fill the entire Header if no gradient is selected. |
ButtonGap | | The gap (in pixels) between each of the buttons drawn in the Header. |
ButtonOffset | | The gap (in pixels) between the right-edge of the last button drawn and the right-edge of the BC. |
ForegroundColor | | The foreground color of the BC. Use this to adjust your HeaderText foreground color. |
GradientMode | | Valid settings are: None , Horizontal , Vertical , ForwardDiagonal , and BackwardDiagonal . |
GradientPercentage | | There is a smooth transition from Begin to Center to End colors in the gradient. This is the percentage at which the middle color will be at 100%. Example: GradientMode =Horizontal and your BC is 100 pixels wide. Setting this to 0.20 will mean that at 20% of the width of the BC, the color will be BackgroundColorCenter ... So, the closer to 0 you set this, the faster the change from Begin to Center will occur, and the closer to 1 you set it, the further that transition will take. |
Height | | The height (in pixels) of the header. All graphics displayed in the header will resize, but keep in mind that if you make the height too small, your users will not see the images properly. |
RoundedCorners | | If True , the BC will display rounded corners in the header. |
RoundSize | | The radius (in pixels) of the 'round' corners. |
ShowActivationMenu | | If True , the Activation button will be displayed. |
ShowClose | | If True , the Close button will be displayed. |
ShowCollapse | | If 'True , the Collapse button will be displayed. |
ShowCollapsePanel | | If True , the Collapse Panel will be displayed whenever the BC is collapsed. |
Text | | This is the text-string that is displayed in the Header. If the text is truncated, ellipses (...) will be drawn at the truncation point. |
TextAlignment | | Left is default. Middle and Right are the other available options. |
Control Events
The following table shows all events that could be raised at run-time.
Resized | | Fires when your Container is collapsed or expanded |
HeaderDoubleClick | | Fires when the user double-clicks the Header |
HeaderClick | | Fires when the user clicks the Header |
ActivationClick | | Fires whenever the Activation button has been clicked; this will fire regardless of whether or not you are using the built-in ContextMenuStrip |
ActivationMenuOpened | | Fires whenever the Activation menu is opened |
ActivationMenuClosed | | Fires whenever the Activation menu is closed |
CloseClicked | | Fires whenever the Close button has been clicked |
DragResizeComplete | | Fires when the User has completed drag-resizing |
DragResizing | | Fires while the BC is being drag-resized |
DragResizeBegin | | Fires when the user begins to drag-resize |
Custom Property Editor - Color Picker
There is a custom property editor included with this project called, 'ColorEditor.' This required several additional steps to implement, all of the details of which can be found in this wonderful article written by Saeed Serpooshan. I made several modifications for my own personal use, but there is simply no way I would have been able to complete this portion of my control without help from that article...so, Thanks Saeed!
Custom Property Display Values
One of the modifications I made was to force the property window to display the value *I* wanted displayed, rather than the default data it wanted to display.
I had problems getting the Custom Property Editor to work on Color
type, and I think that's because Color
already uses a custom editor ... I had to learn how to override that internal custom editor before mine will work... Anyway, to get around it, I store all of my control colors as strings in the format, "###, ###, ###", which are nothing more than simple RGB values. But I did not want the string to be displayed: I wanted the color in the color-box, followed by editable text.
To pull that off, you have to first tell the editor that you are going to override the painted value, and then (of course) you have to provide the new paint method yourself:
Public Overrides Function GetPaintValueSupported(_
ByVal context As System.ComponentModel.ITypeDescriptorContext) As Boolean
Return True
End Function
and here is the overridden Paint
:
Public Overrides Sub PaintValue(ByVal e As System.Drawing.Design.PaintValueEventArgs)
Dim width As Integer = e.Bounds.Width - 1
Dim height As Integer = e.Bounds.Height - 1
Dim brush_HeaderBG As New SolidBrush(_myColor)
e.Graphics.FillRectangle(brush_HeaderBG, 1, 1, width, height)
End Sub
Anti Aliased Text
Anyone out there think this is horrific and complex, and so much work that it's not worth your time and effort? Think again! Normally, if you want to manually paint text, you would do something like this:
Dim text_Rectangle As New RectangleF
text_Rectangle.X = 1
text_Rectangle.Y = 1
text_Rectangle.Width = _width - 1
text_Rectangle.Height = _height - 1
Dim text_Format As New StringFormat
text_Format.Trimming = StringTrimming.EllipsisCharacter
text_Format.Alignment = StringAlignment.Center
text_Format.LineAlignment = StringAlignment.Center
text_Format.FormatFlags = StringFormatFlags.NoWrap
Dim text_Brush As New SolidBrush(SomeColor)
e.Graphics.DrawString("Your Text Goes Here", Me.Font, _
text_Brush, text_Rectangle, text_Format)
But, let's say you want that happy little string to be anti-aliased. GDI gives us everything we need...this is a very complex set of code and not commented very well, so please read carefully!
.
.
.
e.Graphics.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAlias
e.Graphics.DrawString("Your Text Goes Here", Me.Font, _
text_Brush, text_Rectangle, text_Format)
.
.
.
A similar technique can be used for all Drawing methods like the border used to surround the rounded corners:
.
.
.
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
e.Graphics.DrawArc(BorderPen, _PLeft, _PTop, ArcSize, ArcSize, 180, 90)
e.Graphics.DrawArc(BorderPen, _PWidth - ArcSize, _
_PTop, ArcSize, ArcSize, -90, 90)
.
.
.
Trimming the Fat
This last section would be to describe the various areas of the control that can be removed if you're looking for just the basics:
- Activation Menu: Cutting the Activation button and Context Menu would go hand-in-hand with removing the images for that button as well as the code to activate and raise the events. This would be an easy way to trim.
- Collapse Panel: This was added for one specific project I was working on, and I've never used it again - there's not a ton of overhead in including the collapse panel, but this would be another, very easy target for removal.
- Gradient brushes: Unless you're going to require gradient headers, all gradient painting and properties could be removed with very little effort.
- Resizability: The code that allows this is relatively small - you could remove this quite easily, but you would not be saving very much, and most good UIs have the display elements contained within sizable panels.
- BorderForm: This is an entire namespace that you could remove with a single-click, and compile, reducing the size of the DLL significantly.
- Color Picker: Removing this will take a bit more work. It is not as simple as changing the property from the custom editor. Since the parent property is expecting a '
String
' type for this property, you'll have to remove the custom color editor and change the color properties back to type 'Color
'.
Installation
- Unzip the source files and open the BorderContainer project.
- Compile the project.
- Open the Form Toolbox in Visual Studio.
- Right-click on the tab in which you would like to place the control.
- Click 'Choose Items...'.
- From the 'Choose Toolbox Items' dialog box, click 'Browse'.
- Navigate to the Bin folder under BorderContainer (and deeper into either Debug or Release, depending on your settings).
- Click on BorderContainer.dll and click 'Open'.
That's it! The BorderContainer
is now part of your Toolbox and available for use in any of your VB.NET projects.
History
- 07/29/2008: Control first introduced to CodeProject.com.
- 02/10/2010: Bug fixes.