123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713 |
- //#########################################################################################
- //★★★★★★★ http://www.cnpopsoft.com [华普软件] ★★★★★★★
- //★★★★★★★ 华普软件 - VB & C#.NET 专业论文与源码荟萃! ★★★★★★★
- //#########################################################################################
- /*
- * Copyright ?2005, Mathew Hall
- * All rights reserved.
- *
- * DropDownCellEditor.ActivationListener, DropDownCellEditor.ShowDropDown() and
- * DropDownCellEditor.HideDropDown() contains code based on Steve McMahon's
- * PopupWindowHelper (see http://www.vbaccelerator.com/home/NET/Code/Controls/Popup_Windows/Popup_Windows/article.asp)
- *
- * 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.Windows.Forms;
- using XPTable.Events;
- using XPTable.Models;
- using XPTable.Renderers;
- using XPTable.Win32;
- namespace XPTable.Editors
- {
- /// <summary>
- /// A base class for editing Cells that contain drop down buttons
- /// </summary>
- public abstract class DropDownCellEditor : CellEditor, IEditorUsesRendererButtons
- {
- #region Class Data
- /// <summary>
- /// The container that holds the Control displayed when editor is dropped down
- /// </summary>
- private DropDownContainer dropDownContainer;
- /// <summary>
- /// Specifies whether the DropDownContainer is currently displayed
- /// </summary>
- private bool droppedDown;
- /// <summary>
- /// Specifies the DropDown style
- /// </summary>
- private DropDownStyle dropDownStyle;
- /// <summary>
- /// The user defined width of the DropDownContainer
- /// </summary>
- private int dropDownWidth;
- /// <summary>
- /// Listener for WM_NCACTIVATE and WM_ACTIVATEAPP messages
- /// </summary>
- private ActivationListener activationListener;
- /// <summary>
- /// The Form that will own the DropDownContainer
- /// </summary>
- private Form parentForm;
- /// <summary>
- /// Specifies whether the mouse is currently over the
- /// DropDownContainer
- /// </summary>
- private bool containsMouse;
- #endregion
- #region Constructor
-
- /// <summary>
- /// Initializes a new instance of the DropDownCellEditor class with default settings
- /// </summary>
- public DropDownCellEditor() : base()
- {
- TextBox textbox = new TextBox();
- textbox.AutoSize = false;
- textbox.BackColor = SystemColors.Window;
- textbox.BorderStyle = BorderStyle.None;
- textbox.MouseEnter += new EventHandler(textbox_MouseEnter);
- this.Control = textbox;
- this.dropDownContainer = new DropDownContainer(this);
- this.droppedDown = false;
- this.DropDownStyle = DropDownStyle.DropDownList;
- this.dropDownWidth = -1;
- this.parentForm = null;
- this.activationListener = new ActivationListener(this);
- this.containsMouse = false;
- }
- #endregion
- #region Methods
- /// <summary>
- /// Prepares the CellEditor to edit the specified Cell
- /// </summary>
- /// <param name="cell">The Cell to be edited</param>
- /// <param name="table">The Table that contains the Cell</param>
- /// <param name="cellPos">A CellPos representing the position of the Cell</param>
- /// <param name="cellRect">The Rectangle that represents the Cells location and size</param>
- /// <param name="userSetEditorValues">Specifies whether the ICellEditors
- /// starting value has already been set by the user</param>
- /// <returns>true if the ICellEditor can continue editing the Cell, false otherwise</returns>
- public override bool PrepareForEditing(Cell cell, Table table, CellPos cellPos, Rectangle cellRect, bool userSetEditorValues)
- {
- if (!(table.ColumnModel.Columns[cellPos.Column] is DropDownColumn))
- {
- throw new InvalidOperationException("Cannot edit Cell as DropDownCellEditor can only be used with a DropDownColumn");
- }
-
- return base.PrepareForEditing (cell, table, cellPos, cellRect, userSetEditorValues);
- }
- /// <summary>
- /// Starts editing the Cell
- /// </summary>
- public override void StartEditing()
- {
- this.TextBox.KeyPress += new KeyPressEventHandler(OnKeyPress);
- this.TextBox.LostFocus += new EventHandler(OnLostFocus);
-
- base.StartEditing();
- this.parentForm = this.EditingTable.FindForm();
- if (this.DroppedDown)
- {
- this.ShowDropDown();
- }
- this.TextBox.Focus();
- }
- /// <summary>
- /// Stops editing the Cell and commits any changes
- /// </summary>
- public override void StopEditing()
- {
- this.TextBox.KeyPress -= new KeyPressEventHandler(OnKeyPress);
- this.TextBox.LostFocus -= new EventHandler(OnLostFocus);
-
- base.StopEditing();
- this.DroppedDown = false;
- this.parentForm = null;
- }
- /// <summary>
- /// Stops editing the Cell and ignores any changes
- /// </summary>
- public override void CancelEditing()
- {
- this.TextBox.KeyPress -= new KeyPressEventHandler(OnKeyPress);
- this.TextBox.LostFocus -= new EventHandler(OnLostFocus);
-
- base.CancelEditing();
- this.DroppedDown = false;
- this.parentForm = null;
- }
- /// <summary>
- /// Displays the drop down portion to the user
- /// </summary>
- protected virtual void ShowDropDown()
- {
- Point p = this.EditingTable.PointToScreen(this.TextBox.Location);
- p.Y += this.TextBox.Height + 1;
- Rectangle screenBounds = Screen.GetBounds(p);
- if (p.Y + this.dropDownContainer.Height > screenBounds.Bottom)
- {
- p.Y -= this.TextBox.Height + this.dropDownContainer.Height + 1;
- }
- if (p.X + this.dropDownContainer.Width > screenBounds.Right)
- {
- ICellRenderer renderer = this.EditingTable.ColumnModel.GetCellRenderer(this.EditingCellPos.Column);
- int buttonWidth = ((DropDownCellRenderer) renderer).ButtonWidth;
-
- p.X = p.X + this.TextBox.Width + buttonWidth - this.dropDownContainer.Width;
- }
-
- this.dropDownContainer.Location = p;
- this.parentForm.AddOwnedForm(this.dropDownContainer);
- this.activationListener.AssignHandle(this.parentForm.Handle);
- this.dropDownContainer.ShowDropDown();
- this.dropDownContainer.Activate();
- // A little bit of fun. We've shown the popup,
- // but because we've kept the main window's
- // title bar in focus the tab sequence isn't quite
- // right. This can be fixed by sending a tab,
- // but that on its own would shift focus to the
- // second control in the form. So send a tab,
- // followed by a reverse-tab.
- // Send a Tab command:
- NativeMethods.keybd_event((byte) Keys.Tab, 0, 0, 0);
- NativeMethods.keybd_event((byte) Keys.Tab, 0, KeyEventFFlags.KEYEVENTF_KEYUP, 0);
- // Send a reverse Tab command:
- NativeMethods.keybd_event((byte) Keys.ShiftKey, 0, 0, 0);
- NativeMethods.keybd_event((byte) Keys.Tab, 0, 0, 0);
- NativeMethods.keybd_event((byte) Keys.Tab, 0, KeyEventFFlags.KEYEVENTF_KEYUP, 0);
- NativeMethods.keybd_event((byte) Keys.ShiftKey, 0, KeyEventFFlags.KEYEVENTF_KEYUP, 0);
- }
- /// <summary>
- /// Conceals the drop down portion from the user
- /// </summary>
- protected virtual void HideDropDown()
- {
- this.dropDownContainer.HideDropDown();
- this.parentForm.RemoveOwnedForm(this.dropDownContainer);
- this.activationListener.ReleaseHandle();
- this.parentForm.Activate();
- }
- /// <summary>
- /// Gets whether the editor should stop editing if a mouse click occurs
- /// outside of the DropDownContainer while it is dropped down
- /// </summary>
- /// <param name="target">The Control that will receive the message</param>
- /// <param name="cursorPos">The current position of the mouse cursor</param>
- /// <returns>true if the editor should stop editing, false otherwise</returns>
- protected virtual bool ShouldStopEditing(Control target, Point cursorPos)
- {
- return true;
- }
- /// <summary>
- /// Filters out a mouse message before it is dispatched
- /// </summary>
- /// <param name="target">The Control that will receive the message</param>
- /// <param name="msg">A WindowMessage that represents the message to process</param>
- /// <param name="wParam">Specifies the WParam field of the message</param>
- /// <param name="lParam">Specifies the LParam field of the message</param>
- /// <returns>true to filter the message and prevent it from being dispatched;
- /// false to allow the message to continue to the next filter or control</returns>
- public override bool ProcessMouseMessage(Control target, WindowMessage msg, int wParam, int lParam)
- {
- if (this.DroppedDown)
- {
- if (msg == WindowMessage.WM_LBUTTONDOWN || msg == WindowMessage.WM_RBUTTONDOWN ||
- msg == WindowMessage.WM_MBUTTONDOWN || msg == WindowMessage.WM_XBUTTONDOWN ||
- msg == WindowMessage.WM_NCLBUTTONDOWN || msg == WindowMessage.WM_NCRBUTTONDOWN ||
- msg == WindowMessage.WM_NCMBUTTONDOWN || msg == WindowMessage.WM_NCXBUTTONDOWN)
- {
- Point cursorPos = Cursor.Position;
-
- if (!this.DropDown.Bounds.Contains(cursorPos))
- {
- if (target != this.EditingTable && target != this.TextBox)
- {
- if (this.ShouldStopEditing(target, cursorPos))
- {
- this.EditingTable.StopEditing();
- }
- }
- }
- }
- else if (msg == WindowMessage.WM_MOUSEMOVE)
- {
- Point cursorPos = Cursor.Position;
-
- if (this.DropDown.Bounds.Contains(cursorPos))
- {
- if (!this.containsMouse)
- {
- this.containsMouse = true;
- this.EditingTable.RaiseCellMouseLeave(this.EditingCellPos);
- }
- }
- else
- {
- this.containsMouse = true;
- }
- }
- }
-
- return false;
- }
- /// <summary>
- /// Filters out a key message before it is dispatched
- /// </summary>
- /// <param name="target">The Control that will receive the message</param>
- /// <param name="msg">A WindowMessage that represents the message to process</param>
- /// <param name="wParam">Specifies the WParam field of the message</param>
- /// <param name="lParam">Specifies the LParam field of the message</param>
- /// <returns>true to filter the message and prevent it from being dispatched;
- /// false to allow the message to continue to the next filter or control</returns>
- public override bool ProcessKeyMessage(Control target, WindowMessage msg, int wParam, int lParam)
- {
- if (msg == WindowMessage.WM_KEYDOWN)
- {
- if (((Keys) wParam) == Keys.F4)
- {
- if (this.TextBox.Focused || this.DropDown.ContainsFocus)
- {
- this.DroppedDown = !this.DroppedDown;
- return true;
- }
- }
- }
- return false;
- }
- #endregion
- #region Properties
- /// <summary>
- /// Gets the TextBox used to edit the Cells contents
- /// </summary>
- protected TextBox TextBox
- {
- get
- {
- return this.Control as TextBox;
- }
- }
- /// <summary>
- /// Gets the container that holds the Control displayed when editor is dropped down
- /// </summary>
- protected DropDownContainer DropDown
- {
- get
- {
- return this.dropDownContainer;
- }
- }
- /// <summary>
- /// Gets or sets whether the editor is displaying its drop-down portion
- /// </summary>
- public bool DroppedDown
- {
- get
- {
- return this.droppedDown;
- }
- set
- {
- if (this.droppedDown != value)
- {
- this.droppedDown = value;
- if (value)
- {
- this.ShowDropDown();
- }
- else
- {
- this.HideDropDown();
- }
- }
- }
- }
- /// <summary>
- /// Gets or sets the width of the of the drop-down portion of the editor
- /// </summary>
- public int DropDownWidth
- {
- get
- {
- if (this.dropDownWidth != -1)
- {
- return this.dropDownWidth;
- }
-
- return this.dropDownContainer.Width;
- }
- set
- {
- this.dropDownWidth = value;
- this.dropDownContainer.Width = value;
- }
- }
- /// <summary>
- /// Gets the user defined width of the of the drop-down portion of the editor
- /// </summary>
- internal int InternalDropDownWidth
- {
- get
- {
- return this.dropDownWidth;
- }
- }
- /// <summary>
- /// Gets or sets a value specifying the style of the drop down editor
- /// </summary>
- public DropDownStyle DropDownStyle
- {
- get
- {
- return this.dropDownStyle;
- }
- set
- {
- if (!Enum.IsDefined(typeof(DropDownStyle), value))
- {
- throw new InvalidEnumArgumentException("value", (int) value, typeof(DropDownStyle));
- }
-
- if (this.dropDownStyle != value)
- {
- this.dropDownStyle = value;
- this.TextBox.ReadOnly = (value == DropDownStyle.DropDownList);
- }
- }
- }
- /// <summary>
- /// Gets or sets the text that is selected in the editable portion of the editor
- /// </summary>
- public string SelectedText
- {
- get
- {
- if (this.DropDownStyle == DropDownStyle.DropDownList)
- {
- return "";
- }
- return this.TextBox.SelectedText;
- }
- set
- {
- if (this.DropDownStyle != DropDownStyle.DropDownList && value != null)
- {
- this.TextBox.SelectedText = value;
- }
- }
- }
- /// <summary>
- /// Gets or sets the number of characters selected in the editable portion
- /// of the editor
- /// </summary>
- public int SelectionLength
- {
- get
- {
- return this.TextBox.SelectionLength;
- }
- set
- {
- this.TextBox.SelectionLength = value;
- }
- }
- /// <summary>
- /// Gets or sets the starting index of text selected in the editor
- /// </summary>
- public int SelectionStart
- {
- get
- {
- return this.TextBox.SelectionStart;
- }
- set
- {
- this.TextBox.SelectionStart = value;
- }
- }
- /// <summary>
- /// Gets or sets the text associated with the editor
- /// </summary>
- public string Text
- {
- get
- {
- return this.TextBox.Text;
- }
- set
- {
- this.TextBox.Text = value;
- }
- }
- #endregion
-
- #region Events
- /// <summary>
- /// Handler for the editors TextBox.KeyPress event
- /// </summary>
- /// <param name="sender">The object that raised the event</param>
- /// <param name="e">A KeyPressEventArgs that contains the event data</param>
- protected virtual void OnKeyPress(object sender, KeyPressEventArgs e)
- {
- if (e.KeyChar == AsciiChars.CarriageReturn /*Enter*/)
- {
- if (this.EditingTable != null)
- {
- this.EditingTable.StopEditing();
- }
- }
- else if (e.KeyChar == AsciiChars.Escape)
- {
- if (this.EditingTable != null)
- {
- this.EditingTable.CancelEditing();
- }
- }
- }
- /// <summary>
- /// Handler for the editors TextBox.LostFocus event
- /// </summary>
- /// <param name="sender">The object that raised the event</param>
- /// <param name="e">An EventArgs that contains the event data</param>
- protected virtual void OnLostFocus(object sender, EventArgs e)
- {
- if (this.TextBox.Focused || this.DropDown.ContainsFocus)
- {
- return;
- }
-
- if (this.EditingTable != null)
- {
- this.EditingTable.StopEditing();
- }
- }
-
- /// <summary>
- /// Handler for the editors drop down button MouseDown event
- /// </summary>
- /// <param name="sender">The object that raised the event</param>
- /// <param name="e">A CellMouseEventArgs that contains the event data</param>
- public virtual void OnEditorButtonMouseDown(object sender, CellMouseEventArgs e)
- {
- this.DroppedDown = !this.DroppedDown;
- }
- /// <summary>
- /// Handler for the editors drop down button MouseUp event
- /// </summary>
- /// <param name="sender">The object that raised the event</param>
- /// <param name="e">A CellMouseEventArgs that contains the event data</param>
- public virtual void OnEditorButtonMouseUp(object sender, CellMouseEventArgs e)
- {
-
- }
- /// <summary>
- /// Handler for the editors textbox MouseEnter event
- /// </summary>
- /// <param name="sender">The object that raised the event</param>
- /// <param name="e">An EventArgs that contains the event data</param>
- private void textbox_MouseEnter(object sender, EventArgs e)
- {
- this.EditingTable.RaiseCellMouseLeave(this.EditingCellPos);
- }
- #endregion
- #region ActivationListener
- /// <summary>
- /// Listener for WM_NCACTIVATE and WM_ACTIVATEAPP messages
- /// </summary>
- internal class ActivationListener : XPTable.Win32.NativeWindow
- {
- /// <summary>
- /// The DropDownCellEditor that owns the listener
- /// </summary>
- private DropDownCellEditor owner;
- /// <summary>
- /// Initializes a new instance of the DropDownCellEditor class with the
- /// specified DropDownCellEditor owner
- /// </summary>
- /// <param name="owner">The DropDownCellEditor that owns the listener</param>
- public ActivationListener(DropDownCellEditor owner) : base()
- {
- this.owner = owner;
- }
- /// <summary>
- /// Gets or sets the DropDownCellEditor that owns the listener
- /// </summary>
- public DropDownCellEditor Editor
- {
- get
- {
- return this.owner;
- }
- set
- {
- this.owner = value;
- }
- }
- /// <summary>
- /// Processes Windows messages
- /// </summary>
- /// <param name="m">The Windows Message to process</param>
- protected override void WndProc(ref Message m)
- {
- base.WndProc(ref m);
-
- if (this.owner != null && this.owner.DroppedDown)
- {
- if (m.Msg == (int) WindowMessage.WM_NCACTIVATE)
- {
- if (((int) m.WParam) == 0)
- {
- NativeMethods.SendMessage(this.Handle, (int) WindowMessage.WM_NCACTIVATE, 1, 0);
- }
- }
- else if (m.Msg == (int) WindowMessage.WM_ACTIVATEAPP)
- {
- if ((int)m.WParam == 0)
- {
- this.owner.DroppedDown = false;
-
- NativeMethods.PostMessage(this.Handle, (int) WindowMessage.WM_NCACTIVATE, 0, 0);
- }
- }
- }
- }
- }
- #endregion
- }
- }
|