//######################################################################################### //★★★★★★★ 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.ComponentModel; using System.Drawing; using System.Globalization; using System.Windows.Forms; using XPTable.Events; using XPTable.Models; using XPTable.Themes; namespace XPTable.Renderers { /// /// A CellRenderer that draws Cell contents as CheckBoxes /// public class CheckBoxCellRenderer : CellRenderer { #region Class Data /// /// The size of the checkbox /// private Size checkSize; /// /// Specifies whether any text contained in the Cell should be drawn /// private bool drawText; #endregion #region Constructor /// /// Initializes a new instance of the CheckBoxCellRenderer class with /// default settings /// public CheckBoxCellRenderer() : base() { this.checkSize = new Size(13, 13); this.drawText = true; } #endregion #region Methods /// /// Gets the Rectangle that specifies the Size and Location of /// the check box contained in the current Cell /// /// A Rectangle that specifies the Size and Location of /// the check box contained in the current Cell protected Rectangle CalcCheckRect(RowAlignment rowAlignment, ColumnAlignment columnAlignment) { Rectangle checkRect = new Rectangle(this.ClientRectangle.Location, this.CheckSize); if (checkRect.Height > this.ClientRectangle.Height) { checkRect.Height = this.ClientRectangle.Height; checkRect.Width = checkRect.Height; } switch (rowAlignment) { case RowAlignment.Center: { checkRect.Y += (this.ClientRectangle.Height - checkRect.Height) / 2; break; } case RowAlignment.Bottom: { checkRect.Y = this.ClientRectangle.Bottom - checkRect.Height; break; } } if (!this.DrawText) { if (columnAlignment == ColumnAlignment.Center) { checkRect.X += (this.ClientRectangle.Width - checkRect.Width) / 2; } else if (columnAlignment == ColumnAlignment.Right) { checkRect.X = this.ClientRectangle.Right - checkRect.Width; } } return checkRect; } /// /// Gets the CheckBoxCellRenderer specific data used by the Renderer from /// the specified Cell /// /// The Cell to get the CheckBoxCellRenderer data for /// The CheckBoxCellRenderer data for the specified Cell protected CheckBoxRendererData GetCheckBoxRendererData(Cell cell) { object rendererData = this.GetRendererData(cell); if (rendererData == null || !(rendererData is CheckBoxRendererData)) { if (cell.CheckState == CheckState.Unchecked) { rendererData = new CheckBoxRendererData(CheckBoxStates.UncheckedNormal); } else if (cell.CheckState == CheckState.Indeterminate && cell.ThreeState) { rendererData = new CheckBoxRendererData(CheckBoxStates.MixedNormal); } else { rendererData = new CheckBoxRendererData(CheckBoxStates.CheckedNormal); } this.SetRendererData(cell, rendererData); } this.ValidateCheckState(cell, (CheckBoxRendererData) rendererData); return (CheckBoxRendererData) rendererData; } /// /// Corrects any differences between the check state of the specified Cell /// and the check state in its rendererData /// /// The Cell to chech /// The CheckBoxRendererData to check private void ValidateCheckState(Cell cell, CheckBoxRendererData rendererData) { switch (cell.CheckState) { case CheckState.Checked: { if (rendererData.CheckState <= CheckBoxStates.UncheckedDisabled) { rendererData.CheckState |= (CheckBoxStates) 4; } else if (rendererData.CheckState >= CheckBoxStates.MixedNormal) { rendererData.CheckState -= (CheckBoxStates) 4; } break; } case CheckState.Indeterminate: { if (rendererData.CheckState <= CheckBoxStates.UncheckedDisabled) { rendererData.CheckState |= (CheckBoxStates) 8; } else if (rendererData.CheckState <= CheckBoxStates.CheckedDisabled) { rendererData.CheckState |= (CheckBoxStates) 4; } break; } default: { if (rendererData.CheckState >= CheckBoxStates.MixedNormal) { rendererData.CheckState -= (CheckBoxStates) 8; } else if (rendererData.CheckState >= CheckBoxStates.CheckedNormal) { rendererData.CheckState -= (CheckBoxStates) 4; } break; } } } #endregion #region Properties /// /// Gets the size of the checkbox /// protected Size CheckSize { get { return this.checkSize; } } /// /// Gets or sets whether any text contained in the Cell should be drawn /// public bool DrawText { get { return this.drawText; } } #endregion #region Events #region Keys /// /// Raises the KeyDown event /// /// A CellKeyEventArgs that contains the event data public override void OnKeyDown(CellKeyEventArgs e) { base.OnKeyDown(e); if (e.KeyData == Keys.Space && e.Table.IsCellEditable(e.CellPos)) { // get the renderer data CheckBoxRendererData rendererData = this.GetCheckBoxRendererData(e.Cell); // if (e.Cell.CheckState == CheckState.Checked) { rendererData.CheckState = CheckBoxStates.CheckedPressed; } else if (e.Cell.CheckState == CheckState.Indeterminate) { rendererData.CheckState = CheckBoxStates.MixedPressed; } else //if (e.Cell.CheckState == CheckState.Unchecked) { rendererData.CheckState = CheckBoxStates.UncheckedPressed; } e.Table.Invalidate(e.CellRect); } } /// /// Raises the KeyUp event /// /// A CellKeyEventArgs that contains the event data public override void OnKeyUp(CellKeyEventArgs e) { base.OnKeyUp(e); if (e.KeyData == Keys.Space && e.Table.IsCellEditable(e.CellPos)) { // get the renderer data CheckBoxRendererData rendererData = this.GetCheckBoxRendererData(e.Cell); // if (e.Cell.CheckState == CheckState.Checked) { if (!e.Cell.ThreeState || !(e.Table.ColumnModel.Columns[e.Column] is CheckBoxColumn) || ((CheckBoxColumn) e.Table.ColumnModel.Columns[e.Column]).CheckStyle == CheckBoxColumnStyle.RadioButton) { rendererData.CheckState = CheckBoxStates.UncheckedNormal; e.Cell.CheckState = CheckState.Unchecked; } else { rendererData.CheckState = CheckBoxStates.MixedNormal; e.Cell.CheckState = CheckState.Indeterminate; } } else if (e.Cell.CheckState == CheckState.Indeterminate) { rendererData.CheckState = CheckBoxStates.UncheckedNormal; e.Cell.CheckState = CheckState.Unchecked; } else //if (e.Cell.CheckState == CheckState.Unchecked) { rendererData.CheckState = CheckBoxStates.CheckedNormal; e.Cell.CheckState = CheckState.Checked; } e.Table.Invalidate(e.CellRect); } } #endregion #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 (e.Table.IsCellEditable(e.CellPos)) { // get the renderer data CheckBoxRendererData rendererData = this.GetCheckBoxRendererData(e.Cell); if (e.Cell.CheckState == CheckState.Checked) { if (rendererData.CheckState != CheckBoxStates.CheckedNormal) { rendererData.CheckState = CheckBoxStates.CheckedNormal; e.Table.Invalidate(e.CellRect); } } else if (e.Cell.CheckState == CheckState.Indeterminate) { if (rendererData.CheckState != CheckBoxStates.MixedNormal) { rendererData.CheckState = CheckBoxStates.MixedNormal; e.Table.Invalidate(e.CellRect); } } else //if (e.Cell.CheckState == CheckState.Unchecked) { if (rendererData.CheckState != CheckBoxStates.UncheckedNormal) { rendererData.CheckState = CheckBoxStates.UncheckedNormal; 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 (e.Table.IsCellEditable(e.CellPos)) { // get the renderer data CheckBoxRendererData rendererData = this.GetCheckBoxRendererData(e.Cell); if (this.CalcCheckRect(e.Table.TableModel.Rows[e.Row].Alignment, e.Table.ColumnModel.Columns[e.Column].Alignment).Contains(e.X, e.Y)) { if (e.Button == MouseButtons.Left && e.Table.LastMouseDownCell.Row == e.Row && e.Table.LastMouseDownCell.Column == e.Column) { // if (e.Cell.CheckState == CheckState.Checked) { if (!e.Cell.ThreeState || !(e.Table.ColumnModel.Columns[e.Column] is CheckBoxColumn) || ((CheckBoxColumn) e.Table.ColumnModel.Columns[e.Column]).CheckStyle == CheckBoxColumnStyle.RadioButton) { rendererData.CheckState = CheckBoxStates.UncheckedHot; e.Cell.CheckState = CheckState.Unchecked; } else { rendererData.CheckState = CheckBoxStates.MixedHot; e.Cell.CheckState = CheckState.Indeterminate; } } else if (e.Cell.CheckState == CheckState.Indeterminate) { rendererData.CheckState = CheckBoxStates.UncheckedHot; e.Cell.CheckState = CheckState.Unchecked; } else //if (e.Cell.CheckState == CheckState.Unchecked) { rendererData.CheckState = CheckBoxStates.CheckedHot; e.Cell.CheckState = CheckState.Checked; } 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 (e.Table.IsCellEditable(e.CellPos)) { // get the renderer data CheckBoxRendererData rendererData = this.GetCheckBoxRendererData(e.Cell); if (this.CalcCheckRect(e.Table.TableModel.Rows[e.Row].Alignment, e.Table.ColumnModel.Columns[e.Column].Alignment).Contains(e.X, e.Y)) { // if (e.Cell.CheckState == CheckState.Checked) { rendererData.CheckState = CheckBoxStates.CheckedPressed; } else if (e.Cell.CheckState == CheckState.Indeterminate) { rendererData.CheckState = CheckBoxStates.MixedPressed; } else //if (e.Cell.CheckState == CheckState.Unchecked) { rendererData.CheckState = CheckBoxStates.UncheckedPressed; } 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 (e.Table.IsCellEditable(e.CellPos)) { // get the renderer data CheckBoxRendererData rendererData = this.GetCheckBoxRendererData(e.Cell); if (this.CalcCheckRect(e.Table.TableModel.Rows[e.Row].Alignment, e.Table.ColumnModel.Columns[e.Column].Alignment).Contains(e.X, e.Y)) { if (e.Cell.CheckState == CheckState.Checked) { if (rendererData.CheckState == CheckBoxStates.CheckedNormal) { if (e.Button == MouseButtons.Left && e.Row == e.Table.LastMouseDownCell.Row && e.Column == e.Table.LastMouseDownCell.Column) { rendererData.CheckState = CheckBoxStates.CheckedPressed; } else { rendererData.CheckState = CheckBoxStates.CheckedHot; } e.Table.Invalidate(e.CellRect); } } else if (e.Cell.CheckState == CheckState.Indeterminate) { if (rendererData.CheckState == CheckBoxStates.MixedNormal) { if (e.Button == MouseButtons.Left && e.Row == e.Table.LastMouseDownCell.Row && e.Column == e.Table.LastMouseDownCell.Column) { rendererData.CheckState = CheckBoxStates.MixedPressed; } else { rendererData.CheckState = CheckBoxStates.MixedHot; } e.Table.Invalidate(e.CellRect); } } else //if (e.Cell.CheckState == CheckState.Unchecked) { if (rendererData.CheckState == CheckBoxStates.UncheckedNormal) { if (e.Button == MouseButtons.Left && e.Row == e.Table.LastMouseDownCell.Row && e.Column == e.Table.LastMouseDownCell.Column) { rendererData.CheckState = CheckBoxStates.UncheckedPressed; } else { rendererData.CheckState = CheckBoxStates.UncheckedHot; } e.Table.Invalidate(e.CellRect); } } } else { if (e.Cell.CheckState == CheckState.Checked) { rendererData.CheckState = CheckBoxStates.CheckedNormal; } else if (e.Cell.CheckState == CheckState.Indeterminate) { rendererData.CheckState = CheckBoxStates.MixedNormal; } else //if (e.Cell.CheckState == CheckState.Unchecked) { rendererData.CheckState = CheckBoxStates.UncheckedNormal; } 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 CheckBoxColumn) { CheckBoxColumn column = (CheckBoxColumn) e.Table.ColumnModel.Columns[e.Column]; this.checkSize = column.CheckSize; this.drawText = column.DrawText; } else { this.checkSize = new Size(13, 13); this.drawText = true; } base.OnPaintCell(e); } /// /// Raises the Paint event /// /// A PaintCellEventArgs that contains the event data protected override void OnPaint(PaintCellEventArgs e) { base.OnPaint(e); // don't bother if the Cell is null if (e.Cell == null) { return; } Rectangle checkRect = this.CalcCheckRect(this.LineAlignment, this.Alignment); CheckBoxStates state = this.GetCheckBoxRendererData(e.Cell).CheckState; if (!e.Enabled) { if (e.Cell.CheckState == CheckState.Checked) { state = CheckBoxStates.CheckedDisabled; } else if (e.Cell.CheckState == CheckState.Indeterminate) { state = CheckBoxStates.MixedDisabled; } else // if (e.Cell.CheckState == CheckState.Unchecked) { state = CheckBoxStates.UncheckedDisabled; } } if (e.Table.ColumnModel.Columns[e.Column] is CheckBoxColumn && ((CheckBoxColumn) e.Table.ColumnModel.Columns[e.Column]).CheckStyle != CheckBoxColumnStyle.CheckBox) { // remove any mixed states switch (state) { case CheckBoxStates.MixedNormal: state = CheckBoxStates.CheckedNormal; break; case CheckBoxStates.MixedHot: state = CheckBoxStates.CheckedHot; break; case CheckBoxStates.MixedPressed: state = CheckBoxStates.CheckedPressed; break; case CheckBoxStates.MixedDisabled: state = CheckBoxStates.CheckedDisabled; break; } ThemeManager.DrawRadioButton(e.Graphics, checkRect, (RadioButtonStates) state); } else { ThemeManager.DrawCheck(e.Graphics, checkRect, state); } if (this.DrawText) { string text = e.Cell.Text; if (text != null && text.Length != 0) { Rectangle textRect = this.ClientRectangle; textRect.X += checkRect.Width + 1; textRect.Width -= checkRect.Width + 1; if (e.Enabled) { e.Graphics.DrawString(e.Cell.Text, this.Font, this.ForeBrush, textRect, this.StringFormat); } else { e.Graphics.DrawString(e.Cell.Text, this.Font, this.GrayTextBrush, textRect, this.StringFormat); } } } if (e.Focused && e.Enabled) { ControlPaint.DrawFocusRectangle(e.Graphics, this.ClientRectangle); } } #endregion #endregion } }