|
I figured out my own question if someone wants the same effect here is the code...
This Hides the GroupBox Border through color (doesn't diasable it)
set SolidBrush to this.BackColor and use same Rectangle as Rectangle bounds
// Get windows to draw the GroupBox
Rectangle bounds = new Rectangle(ClientRectangle.X, ClientRectangle.Y + 14, ClientRectangle.Width, ClientRectangle.Height - 16);
GroupBoxRenderer.DrawGroupBox(g, bounds, GroupBoxState.Normal);
Pen pen = new Pen(BackColor);
g.FillRectangle(new SolidBrush(this.BackColor), g.FillRectangle(new SolidBrush(this.BackColor), bounds););
|
|
|
|
|
Replace this:
private Rectangle m_toggleRect = new Rectangle(8, 2, 11, 11);
with this:
private Rectangle m_toggleRect = new Rectangle(8, 1, 11, 11);
In DrawGroupBox(), replace this:
Rectangle bounds = new Rectangle(ClientRectangle.X, ClientRectangle.Y + 6, ClientRectangle.Width, ClientRectangle.Height - 6);
GroupBoxRenderer.DrawGroupBox(g, bounds, Enabled ? GroupBoxState.Normal : GroupBoxState.Disabled);
.
.
.
with this:
Rectangle bounds = new Rectangle(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width, ClientRectangle.Height);
GroupBoxRenderer.DrawGroupBox(g, bounds, String.Format(" {0}", Text), this.Font, Enabled ? GroupBoxState.Normal : GroupBoxState.Disabled);
Remove everything else in DrawGroupBox().
The original code put too much space between the groupbox and the control above it and the font color should use the GroupBox font color. Also, using the GroupBoxRenderer.DrawGroupBox() to render the text eliminates the line behind the text effect.
|
|
|
|
|
very good. thank you. now the control is suitable for me.
|
|
|
|
|
Hi and thanks for sharing I learned a few things here.
I have merged your code with code from
GroupBox with an icon: the ImageGroupBox control[^]
To Produce the following result:
Collapsible GroupBox With Icon[^]
I hope that this is ok with you. I thought that since the License was COPL that the use would be acceptable. I have not taken any credit for any of the code and simply referred readers back to the two articles..
|
|
|
|
|
I really like the control, but I was wondering what license it has?
Thanks again!
|
|
|
|
|
There's a bug in Collapsible Groupbox.
After collapsing and uncollapsing, all controls inside groupbox have property Visible set to true (even if before the operation it was set to false).
|
|
|
|
|
To solve this problem, simply goto into IsCollapsed property and change:
public bool IsCollapsed
{
get { return m_collapsed; }
set
{
....
foreach (Control c in Controls)
c.Visible = !value;
Invalidate();
}
}
into:
public bool IsCollapsed
{
get { return m_collapsed; }
set
{
....
Invalidate(false);
}
}
Regards,
Andrea
|
|
|
|
|
The test program throws an exception if you run it with the "Windows Classic" theme on XP as follows:
System.InvalidOperationException: Visual Styles-related operation resulted in an error because no visual style is currently active.
Here is the code that is responsible. It doesn't check to see if a visual style is available before using a VisualStyleRenderer.
void DrawToggleButton(Graphics g)
{
VisualStyleRenderer glyphRender = null;
if (IsCollapsed)
glyphRender = new VisualStyleRenderer(VisualStyleElement.TreeView.Glyph.Closed);
else
glyphRender = new VisualStyleRenderer(VisualStyleElement.TreeView.Glyph.Opened);
glyphRender.DrawBackground(g, m_toggleRect);
}
Here is a fixed version of the function:
void DrawToggleButton(Graphics g)
{
if (Application.RenderWithVisualStyles)
{
VisualStyleRenderer glyphRender = null;
if (IsCollapsed)
glyphRender = new VisualStyleRenderer(VisualStyleElement.TreeView.Glyph.Closed);
else
glyphRender = new VisualStyleRenderer(VisualStyleElement.TreeView.Glyph.Opened);
glyphRender.DrawBackground(g, m_toggleRect);
}
else
{
if (IsCollapsed)
g.DrawImage(PlusImage, m_toggleRect);
else
g.DrawImage(MinusImage, m_toggleRect);
}
}
modified on Tuesday, June 10, 2008 11:54 AM
|
|
|
|
|
Nice control.
i added the following code, to have the parent controls resize on toggle.
HTH,
Sascha Kiefer
<code>
void ResizeParent()
{
int deltaHeight = this.FullHeight - m_collapsedHeight;
this.ResizeParent(this.Parent, !this.Collapsed, deltaHeight);
}
void ResizeParent(Control control, bool collapsed, int deltaHeight)
{
if (control != null)
{
this.ResizeParent(control.Parent, collapsed, deltaHeight);
foreach (Control c in control.Controls)
{
if ((c.Anchor & AnchorStyles.Bottom) != 0)
continue;
Point p = c.Location;
if (p.Y <= this.Location.Y)
continue;
if (collapsed)
p.Y -= deltaHeight;
else
p.Y += deltaHeight;
c.Location = p;
}
Size s = control.Size;
if (collapsed)
s.Height -= deltaHeight;
else
s.Height += deltaHeight;
control.Size = s;
}
}
</code>
void ToggleCollapsed()
{
<code>this.ResizeParent();</code>
this.Collapsed = !this.Collapsed;
if (this.CollapseBoxClickedEvent != null)
this.CollapseBoxClickedEvent(this);
}
|
|
|
|
|
I used your suggestion but have a few problems with it.
When it resizes it has a tendency to relocate components on the form to (-) values for the vertical positioning. One thing I noticed was when I had it in another groupbox - it resized the parent and the parents and changed positioning on the controls that made it unuseable.
It also has a tendency to displace some controls and place others over top of them. - If I have a GroupBox over a Tab Control say 500 pixels wide. I then place the Collapsible GroupBox to the right of the Groupbox (Even into another Collapsible Groupbox - nothing underneath. How can I keep the resize from happening when there is no need to resize parent - or the parents parent. I would rather not add a property to do this - if it could Automagically detect if it needed to resize the parent...
Any ideas ?
modified on Tuesday, June 10, 2008 3:43 PM
|
|
|
|
|
You need to comment ResizeParent() like this:
if (control != null)<br />
{<br />
<br />
foreach (Control c in control.Controls)<br />
{<br />
if ((c.Anchor & AnchorStyles.Bottom) != 0)<br />
continue;<br />
<br />
Point p = c.Location;
|
|
|
|
|
Great article.
I noted that if you change the backgroud color of the form in your tests, the code to draw a line to cover the GroupBox border where the text will sit doesn't work (the line cover the text)
// Draw a line to cover the GroupBox border where the text will sit
g.DrawLine(SystemPens.Control, i_textPos, bounds.Y, i_endPos, bounds.Y);
I have only changed with
Pen pen = new Pen(BackColor);
// Draw a line to cover the GroupBox border where the text will sit
g.DrawLine(pen, i_textPos, bounds.Y, i_endPos, bounds.Y);
I think that's all...
Kind regards,
Marco
modified on Wednesday, July 30, 2008 3:20 PM
|
|
|
|
|
For me i could see the highlight line running through the background of the text so i changed the line to the following as a fix to paint over both the shadow and highlight of the boarder.
Brush lBrush = new SolidBrush( BackColor );
g.FillRectangle( lBrush, i_textPos, bounds.Y, i_endPos - i_textPos, 2 );
|
|
|
|
|
I fixed it this way
SystemPens.FromSystemColor(Parent.BackColor)
|
|
|
|
|
Hey, nice control.
I've got an improvement for it. By adding a class and some attributes, you can enable design-time collapsing of the group box by a mouse click on the box. It will save the size of the non-collapsed group box and all.
It will probably work only for VS 2005 .Net 2.0, haven't checked.
I can make a short article with the implemented details and post it on code project. Or, if you have the time, update the control with these improvements, if you think they actually improve it.
Quite simple. Add a reference to System.Design.dll in your project.
Then add the CollapsibleGroupBoxDesigner class:
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
public class CollapsibleGroupBoxDesigner : System.Windows.Forms.Design.ParentControlDesigner
{
protected override bool GetHitTest(Point point)
{
CollapsibleGroupBox me = this.Control as CollapsibleGroupBox;
if (me.m_toggleRect.Contains(me.PointToClient(point)))
{
return true;
}
return false;
}
}
Then, add the DesignerAttribute atttribute in front of the class itself. Also, you'll need to make the property toggleRect public.
[ToolboxBitmap(typeof(CollapsibleGroupBox))]
[DesignerAttribute(typeof(CollapsibleGroupBoxDesigner))]
public partial class CollapsibleGroupBox : GroupBox
{
....
public Rectangle m_toggleRect = new Rectangle(8, 2, 11, 11);
....
[DefaultValue(false), Browsable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Size FullSize
{
get
{
return m_FullSize;
}
set
{
m_FullSize = value;
}
}
That's probably all, if I'm not missing anything.
Now recompile the project, drop the collapsable group box control on a form in the designer, and click on the toggle box. It should toggle collapse and save it's original size in it's FullSize property.
Works for me quite nicely. Get back to me if you will update the control, please.
Good luck,
Dmitry Sadakov
|
|
|
|
|
I used this in the control - Nice - it lets me know what the thing will look like . I use it in conjunction with the resize parent from another poster.
I am not sure if his resize parent is an issue or if this one is the issue - as I get (-) values on the vertical positioning of some of my other components, during design time.
|
|
|
|
|
I have noticed something in Design time - my control changes namespaces , the system can not find it any more and requests I put Global.Indigo.CollapsibleGroupBox for the namespace - it then works until I click the designer to collapse the control, at that point it disappears.
Any hints, tips or ideas on how to fix this one ?
|
|
|
|
|
Anyone have an idea why localization (ie: use resource manager and reex files) changes the control to width of 503 in the Designer
|
|
|
|
|
Hi,
I would like to contribute my 2cents about this control by adding code to polish up the collapsed look. As of today, the control kept the groupbox even when the control is collapsed.
Replace DrawGroupBox method and theo bolded text are my contribution. =)
<br />
void DrawGroupBox(Graphics g)<br />
{<br />
<br />
Rectangle bounds = new Rectangle(ClientRectangle.X, ClientRectangle.Y + 6, ClientRectangle.Width, ClientRectangle.Height - 6);<br />
<br />
if (m_collapsed)<br />
{<br />
g.DrawLine(SystemPens.ControlDark, bounds.X, bounds.Y, bounds.X + bounds.Width, bounds.Y);<br />
}<br />
else<br />
{<br />
GroupBoxRenderer.DrawGroupBox(g, bounds, Enabled ? GroupBoxState.Normal : GroupBoxState.Disabled);<br />
}<br />
<br />
StringFormat sf = new StringFormat();<br />
int i_textPos = (bounds.X + 8) + m_toggleRect.Width + 2;<br />
int i_textSize = (int)g.MeasureString(Text, this.Font).Width;<br />
i_textSize = i_textSize < 1 ? 1 : i_textSize;<br />
int i_endPos = i_textPos + i_textSize + 1;<br />
<br />
g.DrawLine(SystemPens.Control, i_textPos, bounds.Y, i_endPos, bounds.Y);<br />
<br />
using (SolidBrush drawBrush = new SolidBrush(Color.FromArgb(0, 70, 213)))<br />
g.DrawString(Text, this.Font, drawBrush, i_textPos, 0);<br />
}<br />
|
|
|
|
|
Text boxes I put inside the group box drop one pixel every time I display the form containing the group box in the VS.NET designer.
Anyone knows why?
|
|
|
|
|
Greetings:
I was using this control for a new project where the user can change the color scheme of the aplication and i found some problems, the way it was done assumed that the background color of the groupbox was the default control color, so when it draws de rectangle to in wich it will write the text is filled with the default control color, so i made a small modification so it`s filled with the backcolor.
from this:
g.DrawLine(SystemPens.Control, i_textPos, bounds.Y, i_endPos, bounds.Y);
to this:
g.FillRectangle(new SolidBrush(this.BackColor), 8, 2, i_endPos-8, 12);
I also changed it so it draws the text with the selected ForeColor:
From this:
using (SolidBrush drawBrush = new SolidBrush(Color.FromArgb(0, 70, 213)))
g.DrawString(Text, this.Font, drawBrush, i_textPos, 0);
To this:
using (SolidBrush drawBrush = new SolidBrush(this.ForeColor))
g.DrawString(Text, this.Font, drawBrush, i_textPos, 0);
Also i changed the way of drawing the minus/plus sign from an image to custom drawn and added another 2 color propertys so the user can define the color for the signs(masmenos) and its backcolor(bmasmenos), here is the code i used instead of drawing the images
void DrawToggleButton(Graphics g)
{
g.FillRectangle(new SolidBrush(bmasmenos),m_toggleRect);
g.DrawRectangle(new Pen(masmenos),m_toggleRect.Left+1,m_toggleRect.Top+1,8,8);
g.DrawLine(new Pen(masmenos),m_toggleRect.Left+3,m_toggleRect.Bottom-6,m_toggleRect.Right-4,m_toggleRect.Bottom-6);
if(IsCollapsed)
g.DrawLine(new Pen(masmenos),m_toggleRect.Left+5,m_toggleRect.Top+3,m_toggleRect.Left+5,m_toggleRect.Bottom-4);
}
I also added another method so i could change the default border color
public Color BorderColor
{
get{return m_borderColor;}
set{m_borderColor=value;this.Invalidate();}
}
That`s it, maybe you find this useful for changing the the default apperance of this great control
"Failure is the best reason to start all over again with more knowledge"
-Henry Ford
|
|
|
|
|
I love this component - working great and looks great!
|
|
|
|
|
I second that, just waht i was looking for to keep my interface really organized.
"Failure is the best reason to start all over again with more knowledge"
-Henry Ford
|
|
|
|
|
Hello..
I make the "RightToLeft" Property with value "Yes", but the caption of the Group Box still in the left side...
is the "RightToLeft" Property supported in this component??
Thanks a Lot..
-- modified at 5:44 Sunday 2nd April, 2006
|
|
|
|
|
Thanks a lot friend for valued addition.
|
|
|
|
|