//######################################################################################### //★★★★★★★ http://www.cnpopsoft.com [华普软件] ★★★★★★★ //★★★★★★★ 华普软件 - VB & C#.NET 专业论文与源码荟萃! ★★★★★★★ //######################################################################################### /* * Copyright ?2005, Mathew Hall * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ using System; using System.Drawing; using System.Windows.Forms; using XPTable.Editors; using XPTable.Events; using XPTable.Models; using XPTable.Themes; namespace XPTable.Renderers { /// /// Base class for CellRenderers that Cell contents like ComboBoxes /// public abstract class DropDownCellRenderer : CellRenderer { #region Class Data /// /// The width of the DropDownCellRenderer's dropdown button /// private int buttonWidth; /// /// Specifies whether the DropDownCellRenderer dropdown button should be drawn /// private bool showButton; #endregion #region Constructor /// /// Initializes a new instance of the DropDownCellRenderer class with /// default settings /// protected DropDownCellRenderer() : base() { this.buttonWidth = 15; this.showButton = true; } #endregion #region Methods /// /// Gets the Rectangle that specifies the Size and Location of /// the current Cell's dropdown button /// /// A Rectangle that specifies the Size and Location of /// the current Cell's dropdown button protected internal Rectangle CalcDropDownButtonBounds() { Rectangle buttonRect = this.ClientRectangle; buttonRect.Width = this.ButtonWidth; buttonRect.X = this.ClientRectangle.Right - buttonRect.Width; if (buttonRect.Width > this.ClientRectangle.Width) { buttonRect = this.ClientRectangle; } return buttonRect; } /// /// Gets the DropDownRendererData specific data used by the Renderer from /// the specified Cell /// /// The Cell to get the DropDownRendererData data for /// The DropDownRendererData data for the specified Cell protected DropDownRendererData GetDropDownRendererData(Cell cell) { object rendererData = this.GetRendererData(cell); if (rendererData == null || !(rendererData is DropDownRendererData)) { rendererData = new DropDownRendererData(); this.SetRendererData(cell, rendererData); } return (DropDownRendererData) rendererData; } #endregion #region Properties /// /// Gets or sets the width of the dropdown button /// protected internal int ButtonWidth { get { return this.buttonWidth; } set { this.buttonWidth = value; } } /// /// Gets or sets whether the DropDownCellRenderer dropdown button should be drawn /// protected bool ShowDropDownButton { get { return this.showButton; } set { this.showButton = value; } } #endregion #region Events #region Mouse #region MouseLeave /// /// Raises the MouseLeave event /// /// A CellMouseEventArgs that contains the event data public override void OnMouseLeave(CellMouseEventArgs e) { base.OnMouseLeave(e); if (this.ShowDropDownButton || (e.Table.IsEditing && e.CellPos == e.Table.EditingCell)) { if (e.Table.IsCellEditable(e.CellPos)) { // get the button renderer data DropDownRendererData rendererData = this.GetDropDownRendererData(e.Cell); if (rendererData.ButtonState != ComboBoxStates.Normal) { rendererData.ButtonState = ComboBoxStates.Normal; e.Table.Invalidate(e.CellRect); } } } } #endregion #region MouseUp /// /// Raises the MouseUp event /// /// A CellMouseEventArgs that contains the event data public override void OnMouseUp(CellMouseEventArgs e) { base.OnMouseUp(e); if (this.ShowDropDownButton || (e.Table.IsEditing && e.CellPos == e.Table.EditingCell)) { if (e.Table.IsCellEditable(e.CellPos)) { // get the renderer data DropDownRendererData rendererData = this.GetDropDownRendererData(e.Cell); if (this.CalcDropDownButtonBounds().Contains(e.X, e.Y)) { rendererData.ButtonState = ComboBoxStates.Hot; e.Table.Invalidate(e.CellRect); } } } } #endregion #region MouseDown /// /// Raises the MouseDown event /// /// A CellMouseEventArgs that contains the event data public override void OnMouseDown(CellMouseEventArgs e) { base.OnMouseDown(e); if (this.ShowDropDownButton || (e.Table.IsEditing && e.CellPos == e.Table.EditingCell)) { if (e.Table.IsCellEditable(e.CellPos)) { // get the button renderer data DropDownRendererData rendererData = this.GetDropDownRendererData(e.Cell); if (this.CalcDropDownButtonBounds().Contains(e.X, e.Y)) { if (!(e.Table.ColumnModel.GetCellEditor(e.CellPos.Column) is DropDownCellEditor)) { throw new InvalidOperationException("Cannot edit Cell as DropDownCellRenderer requires a DropDownColumn that uses a DropDownCellEditor"); } rendererData.ButtonState = ComboBoxStates.Pressed; if (!e.Table.IsEditing) { e.Table.EditCell(e.CellPos); } ((IEditorUsesRendererButtons) e.Table.EditingCellEditor).OnEditorButtonMouseDown(this, e); e.Table.Invalidate(e.CellRect); } } } } #endregion #region MouseMove /// /// Raises the MouseMove event /// /// A CellMouseEventArgs that contains the event data public override void OnMouseMove(XPTable.Events.CellMouseEventArgs e) { base.OnMouseMove(e); if (this.ShowDropDownButton || (e.Table.IsEditing && e.CellPos == e.Table.EditingCell)) { if (e.Table.IsCellEditable(e.CellPos)) { // get the button renderer data DropDownRendererData rendererData = this.GetDropDownRendererData(e.Cell); if (this.CalcDropDownButtonBounds().Contains(e.X, e.Y)) { if (rendererData.ButtonState == ComboBoxStates.Normal) { if (e.Button == MouseButtons.Left && e.Row == e.Table.LastMouseDownCell.Row && e.Column == e.Table.LastMouseDownCell.Column) { rendererData.ButtonState = ComboBoxStates.Pressed; } else { rendererData.ButtonState = ComboBoxStates.Hot; } e.Table.Invalidate(e.CellRect); } } else { if (rendererData.ButtonState != ComboBoxStates.Normal) { rendererData.ButtonState = ComboBoxStates.Normal; e.Table.Invalidate(e.CellRect); } } } } } #endregion #endregion #region Paint /// /// Raises the PaintCell event /// /// A PaintCellEventArgs that contains the event data public override void OnPaintCell(PaintCellEventArgs e) { if (e.Table.ColumnModel.Columns[e.Column] is DropDownColumn) { this.showButton = ((DropDownColumn) e.Table.ColumnModel.Columns[e.Column]).ShowDropDownButton; } else { this.showButton = true; } base.OnPaintCell(e); } /// /// Paints the Cells background /// /// A PaintCellEventArgs that contains the event data protected override void OnPaintBackground(PaintCellEventArgs e) { base.OnPaintBackground(e); // don't bother going any further if the Cell is null if (e.Cell == null) { return; } if (this.ShowDropDownButton || (e.Table.IsEditing && e.CellPos == e.Table.EditingCell)) { ComboBoxStates state = this.GetDropDownRendererData(e.Cell).ButtonState; if (!e.Enabled) { state = ComboBoxStates.Disabled; } ThemeManager.DrawComboBoxButton(e.Graphics, this.CalcDropDownButtonBounds(), state); } } #endregion #endregion } }