// ********************************* // 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 { [Designer(typeof(RibbonComboBoxDesigner))] public class RibbonComboBox : RibbonTextBox, IContainsRibbonComponents, IDropDownRibbonItem { #region Fields // Steve private RibbonItem _selectedItem; private readonly Set _assignedHandlers = new Set(); #endregion #region Events /// /// Raised when the DropDown is about to be displayed /// public event EventHandler DropDownShowing; public event RibbonItemEventHandler DropDownItemClicked; public delegate void RibbonItemEventHandler(object sender, RibbonItemEventArgs e); #endregion #region Ctor public RibbonComboBox() { DropDownItems = new RibbonItemCollection(); DropDownItems.SetOwnerItem(this); DropDownVisible = false; AllowTextEdit = true; DrawIconsBar = true; DropDownMaxHeight = 0; _disableTextboxCursor = true; } /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing) { RemoveHandlers(); } base.Dispose(disposing); } #endregion #region Properties /// /// Gets or sets the maximum height for the dropdown window. 0 = autosize. If the size is smaller than the contents then scrollbars will be shown. /// [DefaultValue(0)] [Category("Behavior")] [Description("Gets or sets the maximum height for the dropdown window. 0 = Autosize. If the size is smaller than the contents then scrollbars will be shown.")] public int DropDownMaxHeight { get; set; } /// /// Gets or sets a value indicating if the DropDown portion of the combo box is currently shown. /// [Browsable(false)] [DefaultValue(false)] [Description("Indicates if the dropdown window is currently visible")] public bool DropDownVisible { get; private set; } /// /// Gets or sets a value indicating if the DropDown should be resizable /// [DefaultValue(false)] [Category("Drop Down")] [Description("Makes the DropDown resizable with a grip on the corner")] public bool DropDownResizable { get; set; } /// /// Overriden. /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public override Rectangle TextBoxTextBounds { get { Rectangle r = base.TextBoxTextBounds; r.Width -= DropDownButtonBounds.Width; return r; } } /// /// Gets the collection of items to be displayed on the dropdown /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] [Category("Drop Down")] public RibbonItemCollection DropDownItems { get; } // Steve /// /// Gets the selected of item on the dropdown /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public RibbonItem SelectedItem { get { if (_selectedItem == null) { foreach (RibbonItem item in DropDownItems) { if (item.Text == TextBoxText) { _selectedItem = item; return item; } } return null; } if (DropDownItems.Contains(_selectedItem)) { return _selectedItem; } _selectedItem = null; return null; } //Steve set { if (value == null) { _selectedItem = null; TextBoxText = String.Empty; } else if (value.GetType().BaseType == typeof(RibbonItem)) { if (DropDownItems.Contains(value)) { _selectedItem = value; TextBoxText = _selectedItem.Text; } else { //_dropDownItems.Add(value); _selectedItem = value; TextBoxText = _selectedItem.Text; } } } } [Browsable(true)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public int SelectedIndex { get { if (_selectedItem != null) { return DropDownItems.IndexOf(_selectedItem); } else { return -1; } } set { if (value == -1) { SelectedItem = null; } else { if ((DropDownItems.Count > 0) && (value >= 0) && (value < DropDownItems.Count)) { SelectedItem = DropDownItems[value]; } else { throw new ArgumentOutOfRangeException(nameof(SelectedIndex)); } } } } // Kevin /// /// Gets or sets the value of selected item on the dropdown. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public string SelectedValue { get { if (_selectedItem == null) { return null; } return _selectedItem.Value; } set { foreach (RibbonItem item in DropDownItems) { if (String.Compare(item.Value, value, false) == 0) { if (_selectedItem != item) { _selectedItem = item; TextBoxText = _selectedItem.Text; RibbonItemEventArgs arg = new RibbonItemEventArgs(item); OnDropDownItemClicked(ref arg); } } } } } /// /// Gets the DropDown of the button /// internal RibbonDropDown DropDown { get; private set; } #endregion #region Methods /// /// Raises the event; /// /// public void OnDropDownShowing(EventArgs e) { if (DropDownShowing != null) { DropDownShowing(this, e); } } /// /// Creates the DropDown menu /// protected virtual void CreateDropDown() { DropDown = new RibbonDropDown(this, DropDownItems, Owner); } /// /// Gets or sets if the icons bar should be drawn /// [Category("Drop Down")] [DisplayName("DrawDropDownIconsBar")] [DefaultValue(true)] public bool DrawIconsBar { get; set; } /// /// Shows the DropDown /// public virtual void ShowDropDown() { if (!DropDownVisible) { AssignHandlers(); OnDropDownShowing(EventArgs.Empty); //Highlight (select) the item on the drop down that matches the ComboBox text. foreach (RibbonItem item in DropDownItems) { item.SetSelected(item == SelectedItem); } CreateDropDown(); DropDown.DropDownMaxHeight = DropDownMaxHeight; DropDown.ShowSizingGrip = DropDownResizable; DropDown.DrawIconsBar = DrawIconsBar; DropDown.Closed += DropDown_Closed; Point location = OnGetDropDownMenuLocation(); DropDown.Show(location); DropDownVisible = true; } } private void DropDown_Closed(object sender, EventArgs e) { DropDownVisible = false; //Steve - when popup closed, un-highlight the dropdown arrow and redraw DropDownButtonPressed = false; //Kevin - Unselect it as well DropDownButtonSelected = false; SetSelected(false); RedrawItem(); } private void AssignHandlers() { foreach (RibbonItem item in DropDownItems) { if (_assignedHandlers.Contains(item) == false) { item.Click += DropDownItem_Click; _assignedHandlers.Add(item); } } } private void RemoveHandlers() { foreach (RibbonItem item in _assignedHandlers) { item.Click -= DropDownItem_Click; } _assignedHandlers.Clear(); } private void DropDownItem_Click(object sender, EventArgs e) { // Steve _selectedItem = (sender as RibbonItem); TextBoxText = (sender as RibbonItem).Text; //Kevin Carbis RibbonItemEventArgs ev = new RibbonItemEventArgs(sender as RibbonItem); OnDropDownItemClicked(ref ev); } #endregion #region Overrides protected override bool ClosesDropDownAt(Point p) { return false; } protected override void InitTextBox(TextBox t) { base.InitTextBox(t); t.Width -= DropDownButtonBounds.Width; } public override void SetBounds(Rectangle bounds) { base.SetBounds(bounds); DropDownButtonBounds = Rectangle.FromLTRB( bounds.Right - 15, bounds.Top, bounds.Right + 1, bounds.Bottom + 1); } public virtual void OnDropDownItemClicked(ref RibbonItemEventArgs e) { if (DropDownItemClicked != null) { DropDownItemClicked(this, e); } } public override void OnMouseMove(MouseEventArgs e) { if (!Enabled) return; base.OnMouseMove(e); bool mustRedraw = false; if (DropDownButtonBounds.Contains(e.X, e.Y)) { Owner.Cursor = Cursors.Default; mustRedraw = !DropDownButtonSelected; DropDownButtonSelected = true; } else if (TextBoxBounds.Contains(e.X, e.Y)) { Owner.Cursor = AllowTextEdit ? Cursors.IBeam : Cursors.Default; mustRedraw = DropDownButtonSelected; DropDownButtonSelected = false; } else { Owner.Cursor = Cursors.Default; } if (mustRedraw) { RedrawItem(); } } public override void OnMouseDown(MouseEventArgs e) { if (!Enabled) return; // Steve - if allowtextedit is false, allow the textbox to bring up the popup if (DropDownButtonBounds.Contains(e.X, e.Y) || (TextBoxBounds.Contains(e.X, e.Y) != AllowTextEdit)) { DropDownButtonPressed = true; ShowDropDown(); } else if (TextBoxBounds.Contains(e.X, e.Y) && AllowTextEdit) { StartEdit(); } } public override void OnMouseUp(MouseEventArgs e) { if (!Enabled) return; base.OnMouseUp(e); //Steve - pressed if set false when popup is closed //_dropDownPressed = false; } public override void OnMouseLeave(MouseEventArgs e) { if (!Enabled) return; base.OnMouseLeave(e); DropDownButtonSelected = false; } /// /// Gets the location where the dropdown menu will be shown /// /// internal virtual Point OnGetDropDownMenuLocation() { Point location = Point.Empty; if (Canvas is RibbonDropDown) { location = Canvas.PointToScreen(new Point(TextBoxBounds.Left, Bounds.Bottom)); } else { location = Owner.PointToScreen(new Point(TextBoxBounds.Left, Bounds.Bottom)); } return location; } #endregion #region IContainsRibbonComponents Members public IEnumerable GetAllChildComponents() { return DropDownItems.ToArray(); } #endregion #region IDropDownRibbonItem Members /// /// Gets or sets the bounds of the DropDown button /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Rectangle DropDownButtonBounds { get; private set; } /// /// Gets a value indicating if the DropDown is currently visible /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool DropDownButtonVisible => DropDownVisible; /// /// Gets a value indicating if the DropDown button is currently selected /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool DropDownButtonSelected { get; private set; } /// /// Gets a value indicating if the DropDown button is currently pressed /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool DropDownButtonPressed { get; private set; } internal override void SetOwner(Ribbon owner) { base.SetOwner(owner); DropDownItems.SetOwner(owner); } internal override void SetOwnerPanel(RibbonPanel ownerPanel) { base.SetOwnerPanel(ownerPanel); DropDownItems.SetOwnerPanel(ownerPanel); } internal override void SetOwnerTab(RibbonTab ownerTab) { base.SetOwnerTab(ownerTab); DropDownItems.SetOwnerTab(OwnerTab); } internal override void SetOwnerItem(RibbonItem ownerItem) { base.SetOwnerItem(ownerItem); } internal override void ClearOwner() { List oldItems = new List(DropDownItems); base.ClearOwner(); foreach (RibbonItem item in oldItems) { item.ClearOwner(); } } #endregion } }