// ********************************* // Message from Original Author: // // 2008 Jose Menendez Poo // Please give me credit if you use this code. It's all I ask. // Contact me for more info: menendezpoo@gmail.com // ********************************* // // Original project from http://ribbon.codeplex.com/ // Continue to support and maintain by http://officeribbon.codeplex.com/ using System.Collections.Generic; using System.ComponentModel; using System.Drawing; namespace System.Windows.Forms { /// /// A container for grouping buttons on the Ribbon. Prevents the buttons from being separated the owner panel is resized. /// An example group could be the Bold, Italic and Underline buttons in th eFont panel of Word. The buttons cannot be separated /// and disappear together when the panel size is reduced. /// //[Designer("System.Windows.Forms.RibbonQuickAccessToolbarDesigner")] [Designer(typeof(RibbonItemGroupDesigner))] public class RibbonItemGroup : RibbonItem, IContainsSelectableRibbonItems, IContainsRibbonComponents { #region Fields #endregion #region Ctor public RibbonItemGroup() { Items = new RibbonItemGroupItemCollection(this); Items.SetOwnerItem(this); DrawBackground = true; } public RibbonItemGroup(IEnumerable items) : this() { Items.AddRange(items); } /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && RibbonDesigner.Current == null) { try { foreach (RibbonItem ri in Items) ri.Dispose(); } catch (InvalidOperationException) { if (!IsOpenInVisualStudioDesigner()) { throw; } } } base.Dispose(disposing); } #endregion #region Props /// /// This property is not relevant for this class /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public override bool Checked { get => base.Checked; set => base.Checked = value; } /// /// Gets or sets a value indicating if the group should /// [DefaultValue(true)] [Category("Appearance")] [Description("Background drawing should be avoided when group contains only TextBoxes and ComboBoxes")] public bool DrawBackground { get; set; } /// /// Gets the first item of the group /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public RibbonItem FirstItem { get { if (Items.Count > 0) { return Items[0]; } return null; } } /// /// Gets the last item of the group /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public RibbonItem LastItem { get { if (Items.Count > 0) { return Items[Items.Count - 1]; } return null; } } /// /// Gets the collection of items of this group /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public RibbonItemGroupItemCollection Items { get; } #endregion #region Methods protected override bool ClosesDropDownAt(Point p) { return false; } public override void SetBounds(Rectangle bounds) { base.SetBounds(bounds); int curLeft = bounds.Left; foreach (RibbonItem item in Items) { item.SetBounds(new Rectangle(new Point(curLeft, bounds.Top), item.LastMeasuredSize)); curLeft = item.Bounds.Right + 1; } } public override void OnPaint(object sender, RibbonElementPaintEventArgs e) { if (DrawBackground) { Owner.Renderer.OnRenderRibbonItem(new RibbonItemRenderEventArgs(Owner, e.Graphics, e.Clip, this)); } foreach (RibbonItem item in Items) { if (item.Visible || Owner.IsDesignMode()) item.OnPaint(this, new RibbonElementPaintEventArgs(item.Bounds, e.Graphics, RibbonElementSizeMode.Compact)); } if (DrawBackground) { Owner.Renderer.OnRenderRibbonItemBorder(new RibbonItemRenderEventArgs(Owner, e.Graphics, e.Clip, this)); } } public override Size MeasureSize(object sender, RibbonElementMeasureSizeEventArgs e) { if (!Visible && !Owner.IsDesignMode()) { SetLastMeasuredSize(new Size(0, 0)); return LastMeasuredSize; } //For RibbonItemGroup, size is always compact, and it's designed to be on an horizontal flow //tab panel. // int minWidth = 16; int widthSum = 0; int maxHeight = 16; foreach (RibbonItem item in Items) { Size s = item.MeasureSize(this, new RibbonElementMeasureSizeEventArgs(e.Graphics, RibbonElementSizeMode.Compact)); widthSum += s.Width + 1; maxHeight = Math.Max(maxHeight, s.Height); } widthSum -= 1; widthSum = Math.Max(widthSum, minWidth); if (Site != null && Site.DesignMode) { widthSum += 10; } Size result = new Size(widthSum, maxHeight); SetLastMeasuredSize(result); return result; } /// RibbonPanel where this item is located internal override void SetOwnerPanel(RibbonPanel ownerPanel) { base.SetOwnerPanel(ownerPanel); Items.SetOwnerPanel(ownerPanel); } /// Ribbon that owns this item internal override void SetOwner(Ribbon owner) { base.SetOwner(owner); Items.SetOwner(owner); } /// RibbonTab where this item is located internal override void SetOwnerTab(RibbonTab ownerTab) { base.SetOwnerTab(ownerTab); Items.SetOwnerTab(ownerTab); } /// RibbonItem where this item is located internal override void SetOwnerItem(RibbonItem ownerItem) { base.SetOwnerItem(ownerItem); } internal override void ClearOwner() { List oldItems = new List(Items); base.ClearOwner(); foreach (RibbonItem item in oldItems) { item.ClearOwner(); } } internal override void SetSizeMode(RibbonElementSizeMode sizeMode) { base.SetSizeMode(sizeMode); foreach (RibbonItem item in Items) { item.SetSizeMode(RibbonElementSizeMode.Compact); } } public override string ToString() { return "Group: " + Items.Count + " item(s)"; } #endregion #region IContainsRibbonItems Members public IEnumerable GetItems() { return Items; } public Rectangle GetContentBounds() { return Rectangle.FromLTRB(Bounds.Left + 1, Bounds.Top + 1, Bounds.Right - 1, Bounds.Bottom); } #endregion #region IContainsRibbonComponents Members public IEnumerable GetAllChildComponents() { return Items.ToArray(); } #endregion } }