using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Drawing.Drawing2D; using System.Data; using System.Windows.Forms; using System.ComponentModel.Design; using Demo.WindowsForms.Properties; namespace BSE.Windows.Forms { #region Class XPanderPanel /// /// Used to group collections of controls. /// /// /// XPanderPanel controls represent the expandable and collapsable panels in XPanderPanelList. /// The XpanderPanel is a control that contains other controls. /// You can use a XPanderPanel to group collections of controls such as the XPanderPanelList. /// The order of xpanderpanels in the XPanderPanelList.XPanderPanels collection reflects the order /// of xpanderpanels controls. To change the order of tabs in the control, you must change /// their positions in the collection by removing them and inserting them at new indexes. /// You can change the xpanderpanel's appearance. For example, to make it appear flat, /// set the CaptionStyle property to CaptionStyle.Flat. /// On top of the XPanderPanel there is the captionbar. /// This captionbar may contain an image and text. According to it's properties the panel is closable. /// /// Copyright © 2006-2008 Uwe Eichkorn /// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY /// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE /// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR /// PURPOSE. IT CAN BE DISTRIBUTED FREE OF CHARGE AS LONG AS THIS HEADER /// REMAINS UNCHANGED. /// [Designer(typeof(XPanderPanelDesigner))] [DesignTimeVisible(false)] public partial class XPanderPanel : BasePanel { #region EventsPublic /// /// The CaptionStyleChanged event occurs when CaptionStyle flags have been changed. /// [Description("The CaptionStyleChanged event occurs when CaptionStyle flags have been changed.")] public event EventHandler CaptionStyleChanged; #endregion #region Constants #endregion #region FieldsPrivate private System.Drawing.Image m_imageChevron; private System.Drawing.Image m_imageChevronUp; private System.Drawing.Image m_imageChevronDown; private CustomXPanderPanelColors m_customColors; private System.Drawing.Image m_imageClosePanel; private bool m_bIsClosable = true; private CaptionStyle m_captionStyle; #endregion #region Properties /// /// Gets or sets a value indicating whether the expand icon in a XPanderPanel is visible. /// [Description("Gets or sets a value indicating whether the expand icon in a XPanderPanel is visible.")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [DefaultValue(false)] [Browsable(false)] [Category("Appearance")] public override bool ShowExpandIcon { get { return base.ShowExpandIcon; } set { base.ShowExpandIcon = value; } } /// /// Gets or sets a value indicating whether the close icon in a XPanderPanel is visible. /// [Description("Gets or sets a value indicating whether the close icon in a XPanderPanel is visible.")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [DefaultValue(false)] [Browsable(false)] [Category("Appearance")] public override bool ShowCloseIcon { get { return base.ShowCloseIcon; } set { base.ShowCloseIcon = value; } } /// /// Gets the custom colors which are used for the XPanderPanel. /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] [Description("The custom colors which are used for the XPanderPanel.")] [Category("Appearance")] public CustomXPanderPanelColors CustomColors { get { return this.m_customColors; } } /// /// Gets or sets the style of the caption (not for PanelStyle.Aqua). /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [Browsable(false)] public CaptionStyle CaptionStyle { get { return this.m_captionStyle; } set { if(value.Equals(this.m_captionStyle) == false) { this.m_captionStyle = value; OnCaptionStyleChanged(this, EventArgs.Empty); } } } /// /// Gets or sets a value indicating whether this XPanderPanel is closable. /// [Description("Gets or sets a value indicating whether this XPanderPanel is closable.")] [DefaultValue(true)] [Category("Appearance")] public bool IsClosable { get { return this.m_bIsClosable; } set { if(value.Equals(this.m_bIsClosable) == false) { this.m_bIsClosable = value; this.Invalidate(false); } } } /// /// Gets or sets the height and width of the XPanderPanel. /// [Browsable(false)] public new Size Size { get { return base.Size; } set { base.Size = value; } } #endregion #region MethodsPublic /// /// Initializes a new instance of the XPanderPanel class. /// public XPanderPanel() { InitializeComponent(); this.BackColor = Color.Transparent; this.CaptionStyle = CaptionStyle.Normal; this.ForeColor = SystemColors.ControlText; this.Height = this.CaptionHeight; this.ShowBorder = true; this.m_customColors = new CustomXPanderPanelColors(); this.m_customColors.CustomColorsChanged += OnCustomColorsChanged; } /// /// Gets the rectangle that represents the display area of the XPanderPanel. /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public override Rectangle DisplayRectangle { get { Padding padding = this.Padding; Rectangle displayRectangle = new Rectangle( padding.Left + Constants.BorderThickness, padding.Top + this.CaptionHeight, this.ClientRectangle.Width - padding.Left - padding.Right - (2 * Constants.BorderThickness), this.ClientRectangle.Height - this.CaptionHeight - padding.Top - padding.Bottom); if(this.Controls.Count > 0) { XPanderPanelList xpanderPanelList = this.Controls[0] as XPanderPanelList; if((xpanderPanelList != null) && (xpanderPanelList.Dock == DockStyle.Fill)) { displayRectangle = new Rectangle( padding.Left, padding.Top + this.CaptionHeight, this.ClientRectangle.Width - padding.Left - padding.Right, this.ClientRectangle.Height - this.CaptionHeight - padding.Top - padding.Bottom - Constants.BorderThickness); } } return displayRectangle; } } #endregion #region MethodsProtected /// /// Paints the background of the control. /// /// A PaintEventArgs that contains information about the control to paint. protected override void OnPaintBackground(PaintEventArgs pevent) { base.OnPaintBackground(pevent); base.BackColor = Color.Transparent; Color backColor = this.PanelColors.XPanderPanelBackColor; if((backColor != Color.Empty) && backColor != Color.Transparent) { Rectangle rectangle = new Rectangle( 0, this.CaptionHeight, this.ClientRectangle.Width, this.ClientRectangle.Height - this.CaptionHeight); using(SolidBrush backgroundBrush = new SolidBrush(backColor)) { pevent.Graphics.FillRectangle(backgroundBrush, rectangle); } } } /// /// Raises the Paint event. /// /// A PaintEventArgs that contains the event data. protected override void OnPaint(PaintEventArgs e) { if(IsZeroWidthOrHeight(this.CaptionRectangle) == true) { return; } using(UseAntiAlias antiAlias = new UseAntiAlias(e.Graphics)) { Graphics graphics = e.Graphics; using(UseClearTypeGridFit clearTypeGridFit = new UseClearTypeGridFit(graphics)) { bool bExpand = this.Expand; bool bShowBorder = this.ShowBorder; Color borderColor = this.PanelColors.BorderColor; Rectangle borderRectangle = this.ClientRectangle; switch(this.PanelStyle) { case PanelStyle.Default: case PanelStyle.Office2007: DrawCaptionbar(graphics, bExpand, bShowBorder, this.PanelStyle); CalculatePanelHeights(); DrawBorders(graphics, this); break; } } } } /// /// Raises the PanelExpanding event. /// /// The source of the event. /// A XPanderStateChangeEventArgs that contains the event data. protected override void OnPanelExpanding(object sender, XPanderStateChangeEventArgs e) { bool bExpand = e.Expand; if(bExpand == true) { this.Expand = bExpand; this.Invalidate(false); } base.OnPanelExpanding(sender, e); } /// /// Raises the CaptionStyleChanged event. /// /// The source of the event. /// An EventArgs that contains the event data. protected virtual void OnCaptionStyleChanged(object sender, EventArgs e) { this.Invalidate(this.CaptionRectangle); if(this.CaptionStyleChanged != null) { this.CaptionStyleChanged(sender, e); } } /// /// Raises the MouseUp event. /// /// A MouseEventArgs that contains data about the OnMouseUp event. protected override void OnMouseUp(MouseEventArgs e) { if(this.CaptionRectangle.Contains(e.X, e.Y) == true) { if((this.ShowCloseIcon == false) && (this.ShowExpandIcon == false)) { OnExpandClick(this, EventArgs.Empty); } else if((this.ShowCloseIcon == true) && (this.ShowExpandIcon == false)) { if(this.RectangleCloseIcon.Contains(e.X, e.Y) == false) { OnExpandClick(this, EventArgs.Empty); } } if(this.ShowExpandIcon == true) { if(this.RectangleExpandIcon.Contains(e.X, e.Y) == true) { OnExpandClick(this, EventArgs.Empty); } } if((this.ShowCloseIcon == true) && (this.m_bIsClosable == true)) { if(this.RectangleCloseIcon.Contains(e.X, e.Y) == true) { OnCloseClick(this, EventArgs.Empty); } } } } /// /// Raises the VisibleChanged event. /// /// An EventArgs that contains the event data. protected override void OnVisibleChanged(EventArgs e) { base.OnVisibleChanged(e); if(this.DesignMode == true) { return; } if(this.Visible == false) { if(this.Expand == true) { this.Expand = false; foreach(Control control in this.Parent.Controls) { BSE.Windows.Forms.XPanderPanel xpanderPanel = control as BSE.Windows.Forms.XPanderPanel; if(xpanderPanel != null) { if(xpanderPanel.Visible == true) { xpanderPanel.Expand = true; return; } } } } } #if DEBUG //System.Diagnostics.Trace.WriteLine("Visibility: " + this.Name + this.Visible); #endif CalculatePanelHeights(); } #endregion #region MethodsPrivate private void DrawCaptionbar(Graphics graphics, bool bExpand, bool bShowBorder, PanelStyle panelStyle) { Rectangle captionRectangle = this.CaptionRectangle; Color colorGradientBegin = this.PanelColors.XPanderPanelCaptionGradientBegin; Color colorGradientEnd = this.PanelColors.XPanderPanelCaptionGradientEnd; Color colorGradientMiddle = this.PanelColors.XPanderPanelCaptionGradientMiddle; Color colorText = this.PanelColors.XPanderPanelCaptionText; Color foreColorCloseIcon = this.PanelColors.XPanderPanelCaptionCloseIcon; Color foreColorExpandIcon = this.PanelColors.XPanderPanelCaptionExpandIcon; bool bHover = this.HoverStateCaptionBar == HoverState.Hover ? true : false; if(this.m_imageClosePanel == null) { this.m_imageClosePanel = Resources.closePanel; } if(this.m_imageChevronUp == null) { this.m_imageChevronUp = Resources.ChevronUp; } if(this.m_imageChevronDown == null) { this.m_imageChevronDown = Resources.ChevronDown; } this.m_imageChevron = this.m_imageChevronDown; if(bExpand == true) { this.m_imageChevron = this.m_imageChevronUp; } if(this.m_captionStyle == CaptionStyle.Normal) { if(bHover == true) { colorGradientBegin = this.PanelColors.XPanderPanelSelectedCaptionBegin; colorGradientEnd = this.PanelColors.XPanderPanelSelectedCaptionEnd; colorGradientMiddle = this.PanelColors.XPanderPanelSelectedCaptionMiddle; if(bExpand == true) { colorGradientBegin = this.PanelColors.XPanderPanelPressedCaptionBegin; colorGradientEnd = this.PanelColors.XPanderPanelPressedCaptionEnd; colorGradientMiddle = this.PanelColors.XPanderPanelPressedCaptionMiddle; } colorText = this.PanelColors.XPanderPanelSelectedCaptionText; foreColorCloseIcon = colorText; foreColorExpandIcon = colorText; } else { if(bExpand == true) { colorGradientBegin = this.PanelColors.XPanderPanelCheckedCaptionBegin; colorGradientEnd = this.PanelColors.XPanderPanelCheckedCaptionEnd; colorGradientMiddle = this.PanelColors.XPanderPanelCheckedCaptionMiddle; colorText = this.PanelColors.XPanderPanelSelectedCaptionText; foreColorCloseIcon = colorText; foreColorExpandIcon = colorText; } } if(panelStyle != PanelStyle.Office2007) { RenderDoubleBackgroundGradient( graphics, captionRectangle, colorGradientBegin, colorGradientMiddle, colorGradientEnd, LinearGradientMode.Vertical, false); } else { RenderButtonBackground( graphics, captionRectangle, colorGradientBegin, colorGradientMiddle, colorGradientEnd); } } else { Color colorFlatGradientBegin = this.PanelColors.XPanderPanelFlatCaptionGradientBegin; Color colorFlatGradientEnd = this.PanelColors.XPanderPanelFlatCaptionGradientEnd; Color colorInnerBorder = this.PanelColors.InnerBorderColor; colorText = this.PanelColors.XPanderPanelCaptionText; foreColorExpandIcon = colorText; RenderFlatButtonBackground(graphics, captionRectangle, colorFlatGradientBegin, colorFlatGradientEnd, bHover); DrawInnerBorders(graphics, this); } DrawImagesAndText( graphics, captionRectangle, CaptionSpacing, this.ImageRectangle, this.Image, this.RightToLeft, this.m_bIsClosable, this.ShowCloseIcon, this.m_imageClosePanel, foreColorCloseIcon, ref this.RectangleCloseIcon, this.ShowExpandIcon, this.m_imageChevron, foreColorExpandIcon, ref this.RectangleExpandIcon, this.CaptionFont, colorText, this.Text); } private static void DrawBorders(Graphics graphics, XPanderPanel xpanderPanel) { if(xpanderPanel.ShowBorder == true) { using(GraphicsPath graphicsPath = new GraphicsPath()) { using(Pen borderPen = new Pen(xpanderPanel.PanelColors.BorderColor, Constants.BorderThickness)) { Rectangle captionRectangle = xpanderPanel.CaptionRectangle; Rectangle borderRectangle = captionRectangle; if(xpanderPanel.Expand == true) { borderRectangle = xpanderPanel.ClientRectangle; graphics.DrawLine( borderPen, captionRectangle.Left, captionRectangle.Top + captionRectangle.Height - Constants.BorderThickness, captionRectangle.Left + captionRectangle.Width, captionRectangle.Top + captionRectangle.Height - Constants.BorderThickness); } XPanderPanelList xpanderPanelList = xpanderPanel.Parent as XPanderPanelList; if((xpanderPanelList != null) && (xpanderPanelList.Dock == DockStyle.Fill)) { BSE.Windows.Forms.Panel panel = xpanderPanelList.Parent as BSE.Windows.Forms.Panel; XPanderPanel parentXPanderPanel = xpanderPanelList.Parent as XPanderPanel; if(((panel != null) && (panel.Padding == new Padding(0))) || ((parentXPanderPanel != null) && (parentXPanderPanel.Padding == new Padding(0)))) { if(xpanderPanel.Top != 0) { graphicsPath.AddLine( borderRectangle.Left, borderRectangle.Top, borderRectangle.Left + captionRectangle.Width, borderRectangle.Top); } // Left vertical borderline graphics.DrawLine(borderPen, borderRectangle.Left, borderRectangle.Top, borderRectangle.Left, borderRectangle.Top + borderRectangle.Height); // Right vertical borderline graphics.DrawLine(borderPen, borderRectangle.Left + borderRectangle.Width - Constants.BorderThickness, borderRectangle.Top, borderRectangle.Left + borderRectangle.Width - Constants.BorderThickness, borderRectangle.Top + borderRectangle.Height); } else { // Upper horizontal borderline only at the top xpanderPanel if(xpanderPanel.Top == 0) { graphicsPath.AddLine( borderRectangle.Left, borderRectangle.Top, borderRectangle.Left + borderRectangle.Width, borderRectangle.Top); } // Left vertical borderline graphicsPath.AddLine( borderRectangle.Left, borderRectangle.Top, borderRectangle.Left, borderRectangle.Top + borderRectangle.Height); //Lower horizontal borderline graphicsPath.AddLine( borderRectangle.Left, borderRectangle.Top + borderRectangle.Height - Constants.BorderThickness, borderRectangle.Left + borderRectangle.Width - Constants.BorderThickness, borderRectangle.Top + borderRectangle.Height - Constants.BorderThickness); // Right vertical borderline graphicsPath.AddLine( borderRectangle.Left + borderRectangle.Width - Constants.BorderThickness, borderRectangle.Top, borderRectangle.Left + borderRectangle.Width - Constants.BorderThickness, borderRectangle.Top + borderRectangle.Height); } } else { // Upper horizontal borderline only at the top xpanderPanel if(xpanderPanel.Top == 0) { graphicsPath.AddLine( borderRectangle.Left, borderRectangle.Top, borderRectangle.Left + borderRectangle.Width, borderRectangle.Top); } // Left vertical borderline graphicsPath.AddLine( borderRectangle.Left, borderRectangle.Top, borderRectangle.Left, borderRectangle.Top + borderRectangle.Height); //Lower horizontal borderline graphicsPath.AddLine( borderRectangle.Left, borderRectangle.Top + borderRectangle.Height - Constants.BorderThickness, borderRectangle.Left + borderRectangle.Width - Constants.BorderThickness, borderRectangle.Top + borderRectangle.Height - Constants.BorderThickness); // Right vertical borderline graphicsPath.AddLine( borderRectangle.Left + borderRectangle.Width - Constants.BorderThickness, borderRectangle.Top, borderRectangle.Left + borderRectangle.Width - Constants.BorderThickness, borderRectangle.Top + borderRectangle.Height); } } using(Pen borderPen = new Pen(xpanderPanel.PanelColors.BorderColor, Constants.BorderThickness)) { graphics.DrawPath(borderPen, graphicsPath); } } } } private static void DrawInnerBorders(Graphics graphics, XPanderPanel xpanderPanel) { if(xpanderPanel.ShowBorder == true) { using(GraphicsPath graphicsPath = new GraphicsPath()) { Rectangle captionRectangle = xpanderPanel.CaptionRectangle; XPanderPanelList xpanderPanelList = xpanderPanel.Parent as XPanderPanelList; if((xpanderPanelList != null) && (xpanderPanelList.Dock == DockStyle.Fill)) { BSE.Windows.Forms.Panel panel = xpanderPanelList.Parent as BSE.Windows.Forms.Panel; XPanderPanel parentXPanderPanel = xpanderPanelList.Parent as XPanderPanel; if(((panel != null) && (panel.Padding == new Padding(0))) || ((parentXPanderPanel != null) && (parentXPanderPanel.Padding == new Padding(0)))) { //Left vertical borderline graphicsPath.AddLine(captionRectangle.X, captionRectangle.Y + captionRectangle.Height, captionRectangle.X, captionRectangle.Y + Constants.BorderThickness); if(xpanderPanel.Top == 0) { //Upper horizontal borderline graphicsPath.AddLine(captionRectangle.X, captionRectangle.Y, captionRectangle.X + captionRectangle.Width, captionRectangle.Y); } else { //Upper horizontal borderline graphicsPath.AddLine(captionRectangle.X, captionRectangle.Y + Constants.BorderThickness, captionRectangle.X + captionRectangle.Width, captionRectangle.Y + Constants.BorderThickness); } } } else { //Left vertical borderline graphicsPath.AddLine(captionRectangle.X + Constants.BorderThickness, captionRectangle.Y + captionRectangle.Height, captionRectangle.X + Constants.BorderThickness, captionRectangle.Y); if(xpanderPanel.Top == 0) { //Upper horizontal borderline graphicsPath.AddLine(captionRectangle.X + Constants.BorderThickness, captionRectangle.Y + Constants.BorderThickness, captionRectangle.X + captionRectangle.Width - Constants.BorderThickness, captionRectangle.Y + Constants.BorderThickness); } else { //Upper horizontal borderline graphicsPath.AddLine(captionRectangle.X + Constants.BorderThickness, captionRectangle.Y, captionRectangle.X + captionRectangle.Width - Constants.BorderThickness, captionRectangle.Y); } } using(Pen borderPen = new Pen(xpanderPanel.PanelColors.InnerBorderColor)) { graphics.DrawPath(borderPen, graphicsPath); } } } } private void CalculatePanelHeights() { if(this.Parent == null) { return; } int iPanelHeight = this.Parent.Padding.Top; foreach(Control control in this.Parent.Controls) { BSE.Windows.Forms.XPanderPanel xpanderPanel = control as BSE.Windows.Forms.XPanderPanel; if((xpanderPanel != null) && (xpanderPanel.Visible == true)) { iPanelHeight += xpanderPanel.CaptionHeight; } } iPanelHeight += this.Parent.Padding.Bottom; foreach(Control control in this.Parent.Controls) { BSE.Windows.Forms.XPanderPanel xpanderPanel = control as BSE.Windows.Forms.XPanderPanel; if(xpanderPanel != null) { if(xpanderPanel.Expand == true) { xpanderPanel.Height = this.Parent.Height + xpanderPanel.CaptionHeight - iPanelHeight; } else { xpanderPanel.Height = xpanderPanel.CaptionHeight; } } } int iTop = this.Parent.Padding.Top; foreach(Control control in this.Parent.Controls) { BSE.Windows.Forms.XPanderPanel xpanderPanel = control as BSE.Windows.Forms.XPanderPanel; if((xpanderPanel != null) && (xpanderPanel.Visible == true)) { xpanderPanel.Top = iTop; iTop += xpanderPanel.Height; } } } #endregion } #endregion #region Class XPanderPanelDesigner /// /// Designer class for extending the design mode behavior of a XPanderPanel control /// internal class XPanderPanelDesigner : System.Windows.Forms.Design.ScrollableControlDesigner { #region FieldsPrivate private Pen m_borderPen = new Pen(Color.FromKnownColor(KnownColor.ControlDarkDark)); private System.Windows.Forms.Design.Behavior.Adorner m_adorner; #endregion #region MethodsPublic /// /// Initializes a new instance of the XPanderPanelDesigner class. /// public XPanderPanelDesigner() { this.m_borderPen.DashStyle = DashStyle.Dash; } /// /// Initializes the designer with the specified component. /// /// The IComponent to associate with the designer. public override void Initialize(IComponent component) { base.Initialize(component); XPanderPanel xpanderPanel = Control as XPanderPanel; if(xpanderPanel != null) { this.m_adorner = new System.Windows.Forms.Design.Behavior.Adorner(); BehaviorService.Adorners.Add(this.m_adorner); this.m_adorner.Glyphs.Add(new XPanderPanelCaptionGlyph(BehaviorService, xpanderPanel)); } } #endregion #region MethodsProtected /// /// Releases the unmanaged resources used by the XPanderPanelDesigner, /// and optionally releases the managed resources. /// /// true to release both managed and unmanaged resources; /// false to release only unmanaged resources. protected override void Dispose(bool disposing) { try { if(disposing) { if(this.m_borderPen != null) { this.m_borderPen.Dispose(); } if(this.m_adorner != null) { if(BehaviorService != null) { BehaviorService.Adorners.Remove(this.m_adorner); } } } } finally { base.Dispose(disposing); } } /// /// Receives a call when the control that the designer is managing has painted its surface so the designer can /// paint any additional adornments on top of the xpanderpanel. /// /// A PaintEventArgs the designer can use to draw on the xpanderpanel. protected override void OnPaintAdornments(PaintEventArgs e) { base.OnPaintAdornments(e); e.Graphics.DrawRectangle( this.m_borderPen, 0, 0, this.Control.Width - 2, this.Control.Height - 2); } /// /// Allows a designer to change or remove items from the set of properties that it exposes through a TypeDescriptor. /// /// The properties for the class of the component. protected override void PostFilterProperties(IDictionary properties) { base.PostFilterProperties(properties); properties.Remove("AccessibilityObject"); properties.Remove("AccessibleDefaultActionDescription"); properties.Remove("AccessibleDescription"); properties.Remove("AccessibleName"); properties.Remove("AccessibleRole"); properties.Remove("AllowDrop"); properties.Remove("Anchor"); properties.Remove("AntiAliasing"); properties.Remove("AutoScroll"); properties.Remove("AutoScrollMargin"); properties.Remove("AutoScrollMinSize"); properties.Remove("BackColor"); properties.Remove("BackgroundImage"); properties.Remove("BackgroundImageLayout"); properties.Remove("CausesValidation"); properties.Remove("ContextMenuStrip"); properties.Remove("Dock"); properties.Remove("GenerateMember"); properties.Remove("ImeMode"); properties.Remove("Location"); properties.Remove("MaximumSize"); properties.Remove("MinimumSize"); } #endregion } #endregion #region Class XPanderPanelCaptionGlyph /// /// Represents a single user interface (UI) entity managed by an Adorner. /// internal class XPanderPanelCaptionGlyph : System.Windows.Forms.Design.Behavior.Glyph { #region FieldsPrivate private XPanderPanel m_xpanderPanel; private System.Windows.Forms.Design.Behavior.BehaviorService m_behaviorService; #endregion #region Properties /// /// Gets the bounds of the Glyph. /// public override Rectangle Bounds { get { Point edge = this.m_behaviorService.ControlToAdornerWindow(this.m_xpanderPanel); Rectangle bounds = new Rectangle( edge.X, edge.Y, this.m_xpanderPanel.Width, this.m_xpanderPanel.CaptionHeight); return bounds; } } #endregion #region MethodsPublic /// /// Initializes a new instance of the CaptionGlyph class. /// /// /// public XPanderPanelCaptionGlyph(System.Windows.Forms.Design.Behavior.BehaviorService behaviorService, XPanderPanel xpanderPanel) : base(new XPanderPanelCaptionClickBehavior(xpanderPanel)) { this.m_behaviorService = behaviorService; this.m_xpanderPanel = xpanderPanel; } /// /// Provides hit test logic. /// /// A point to hit-test. /// A Cursor if the Glyph is associated with p; otherwise, a null reference public override Cursor GetHitTest(Point p) { // GetHitTest is called to see if the point is // within this glyph. This gives us a chance to decide // what cursor to show. Returning null from here means // the mouse pointer is not currently inside of the glyph. // Returning a valid cursor here indicates the pointer is // inside the glyph, and also enables our Behavior property // as the active behavior. if((this.m_xpanderPanel != null) && (this.m_xpanderPanel.Expand == false) && (Bounds.Contains(p))) { return Cursors.Hand; } return null; } /// /// Provides paint logic. /// /// A PaintEventArgs that contains the event data. public override void Paint(PaintEventArgs pe) { } #endregion } #endregion #region Class XPanderPanelCaptionClickBehavior /// /// Designer behaviour when the user clicks in the glyph on the XPanderPanel caption /// internal class XPanderPanelCaptionClickBehavior : System.Windows.Forms.Design.Behavior.Behavior { #region FieldsPrivate private XPanderPanel m_xpanderPanel; #endregion #region MethodsPublic /// /// Initializes a new instance of the Behavior class. /// /// XPanderPanel for this behaviour public XPanderPanelCaptionClickBehavior(XPanderPanel xpanderPanel) { this.m_xpanderPanel = xpanderPanel; } /// /// Called when any mouse-down message enters the adorner window of the BehaviorService. /// /// A Glyph. /// A MouseButtons value indicating which button was clicked. /// The location at which the click occurred. /// true if the message was handled; otherwise, false. public override bool OnMouseDown(System.Windows.Forms.Design.Behavior.Glyph g, MouseButtons button, Point mouseLoc) { if((this.m_xpanderPanel != null) && (this.m_xpanderPanel.Expand == false)) { XPanderPanelList xpanderPanelList = this.m_xpanderPanel.Parent as XPanderPanelList; if(xpanderPanelList != null) { xpanderPanelList.Expand(this.m_xpanderPanel); this.m_xpanderPanel.Invalidate(false); } } return true; // indicating we processed this event. } #endregion } #endregion }