ComboBoxCellEditor.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. //#########################################################################################
  2. //★★★★★★★ http://www.cnpopsoft.com [华普软件] ★★★★★★★
  3. //★★★★★★★ 华普软件 - VB & C#.NET 专业论文与源码荟萃! ★★★★★★★
  4. //#########################################################################################
  5. /*
  6. * Copyright ?2005, Mathew Hall
  7. * All rights reserved.
  8. *
  9. * Redistribution and use in source and binary forms, with or without modification,
  10. * are permitted provided that the following conditions are met:
  11. *
  12. * - Redistributions of source code must retain the above copyright notice,
  13. * this list of conditions and the following disclaimer.
  14. *
  15. * - Redistributions in binary form must reproduce the above copyright notice,
  16. * this list of conditions and the following disclaimer in the documentation
  17. * and/or other materials provided with the distribution.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  21. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  22. * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  23. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  24. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  25. * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  26. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  27. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  28. * OF SUCH DAMAGE.
  29. */
  30. using System;
  31. using System.ComponentModel;
  32. using System.Drawing;
  33. using System.Windows.Forms;
  34. using XPTable.Models;
  35. using XPTable.Renderers;
  36. using XPTable.Win32;
  37. namespace XPTable.Editors
  38. {
  39. /// <summary>
  40. /// A class for editing Cells that look like a ComboBox
  41. /// </summary>
  42. public class ComboBoxCellEditor : DropDownCellEditor
  43. {
  44. #region EventHandlers
  45. /// <summary>
  46. /// Occurs when the SelectedIndex property has changed
  47. /// </summary>
  48. public event EventHandler SelectedIndexChanged;
  49. /// <summary>
  50. /// Occurs when a visual aspect of an owner-drawn ComboBoxCellEditor changes
  51. /// </summary>
  52. public event DrawItemEventHandler DrawItem;
  53. /// <summary>
  54. /// Occurs each time an owner-drawn ComboBoxCellEditor item needs to be
  55. /// drawn and when the sizes of the list items are determined
  56. /// </summary>
  57. public event MeasureItemEventHandler MeasureItem;
  58. #endregion
  59. #region Class Data
  60. /// <summary>
  61. /// The ListBox that contains the items to be shown in the
  62. /// drop-down portion of the ComboBoxCellEditor
  63. /// </summary>
  64. private ListBox listbox;
  65. /// <summary>
  66. /// The maximum number of items to be shown in the drop-down
  67. /// portion of the ComboBoxCellEditor
  68. /// </summary>
  69. private int maxDropDownItems;
  70. /// <summary>
  71. /// The width of the Cell being edited
  72. /// </summary>
  73. private int cellWidth;
  74. #endregion
  75. #region Constructor
  76. /// <summary>
  77. /// Initializes a new instance of the ComboBoxCellEditor class with default settings
  78. /// </summary>
  79. public ComboBoxCellEditor() : base()
  80. {
  81. this.listbox = new ListBox();
  82. this.listbox.BorderStyle = BorderStyle.None;
  83. this.listbox.Location = new Point(0, 0);
  84. this.listbox.Size = new Size(100, 100);
  85. this.listbox.Dock = DockStyle.Fill;
  86. this.listbox.DrawItem += new DrawItemEventHandler(this.listbox_DrawItem);
  87. this.listbox.MeasureItem += new MeasureItemEventHandler(this.listbox_MeasureItem);
  88. this.listbox.MouseEnter += new EventHandler(this.listbox_MouseEnter);
  89. this.listbox.KeyDown += new KeyEventHandler(this.OnKeyDown);
  90. this.listbox.KeyPress += new KeyPressEventHandler(base.OnKeyPress);
  91. this.listbox.Click += new EventHandler(listbox_Click);
  92. this.TextBox.KeyDown += new KeyEventHandler(OnKeyDown);
  93. this.TextBox.MouseWheel += new MouseEventHandler(OnMouseWheel);
  94. this.maxDropDownItems = 8;
  95. this.cellWidth = 0;
  96. this.DropDown.Control = this.listbox;
  97. }
  98. #endregion
  99. #region Methods
  100. /// <summary>
  101. /// Sets the location and size of the CellEditor
  102. /// </summary>
  103. /// <param name="cellRect">A Rectangle that represents the size and location
  104. /// of the Cell being edited</param>
  105. protected override void SetEditLocation(Rectangle cellRect)
  106. {
  107. // calc the size of the textbox
  108. ICellRenderer renderer = this.EditingTable.ColumnModel.GetCellRenderer(this.EditingCellPos.Column);
  109. int buttonWidth = ((ComboBoxCellRenderer) renderer).ButtonWidth;
  110. this.TextBox.Size = new Size(cellRect.Width - 1 - buttonWidth, cellRect.Height-1);
  111. this.TextBox.Location = cellRect.Location;
  112. this.cellWidth = cellRect.Width;
  113. }
  114. /// <summary>
  115. /// Sets the initial value of the editor based on the contents of
  116. /// the Cell being edited
  117. /// </summary>
  118. protected override void SetEditValue()
  119. {
  120. this.TextBox.Text = this.EditingCell.Text;
  121. this.listbox.SelectedItem = this.EditingCell.Text;
  122. }
  123. /// <summary>
  124. /// Sets the contents of the Cell being edited based on the value
  125. /// in the editor
  126. /// </summary>
  127. protected override void SetCellValue()
  128. {
  129. this.EditingCell.Text = this.TextBox.Text;
  130. }
  131. /// <summary>
  132. /// Starts editing the Cell
  133. /// </summary>
  134. public override void StartEditing()
  135. {
  136. this.listbox.SelectedIndexChanged += new EventHandler(listbox_SelectedIndexChanged);
  137. base.StartEditing();
  138. }
  139. /// <summary>
  140. /// Stops editing the Cell and commits any changes
  141. /// </summary>
  142. public override void StopEditing()
  143. {
  144. this.listbox.SelectedIndexChanged -= new EventHandler(listbox_SelectedIndexChanged);
  145. base.StopEditing();
  146. }
  147. /// <summary>
  148. /// Stops editing the Cell and ignores any changes
  149. /// </summary>
  150. public override void CancelEditing()
  151. {
  152. this.listbox.SelectedIndexChanged -= new EventHandler(listbox_SelectedIndexChanged);
  153. base.CancelEditing();
  154. }
  155. /// <summary>
  156. /// Displays the drop down portion to the user
  157. /// </summary>
  158. protected override void ShowDropDown()
  159. {
  160. if (this.InternalDropDownWidth == -1)
  161. {
  162. this.DropDown.Width = this.cellWidth;
  163. this.listbox.Width = this.cellWidth;
  164. }
  165. if (this.IntegralHeight)
  166. {
  167. int visItems = this.listbox.Height / this.ItemHeight;
  168. if (visItems > this.MaxDropDownItems)
  169. {
  170. visItems = this.MaxDropDownItems;
  171. }
  172. if (this.listbox.Items.Count < this.MaxDropDownItems)
  173. {
  174. visItems = this.listbox.Items.Count;
  175. }
  176. if (visItems == 0)
  177. {
  178. visItems = 1;
  179. }
  180. this.DropDown.Height = (visItems * this.ItemHeight) + 2;
  181. this.listbox.Height = visItems * this.ItemHeight;
  182. }
  183. base.ShowDropDown();
  184. }
  185. #endregion
  186. #region Properties
  187. /// <summary>
  188. /// Gets or sets the maximum number of items to be shown in the drop-down
  189. /// portion of the ComboBoxCellEditor
  190. /// </summary>
  191. public int MaxDropDownItems
  192. {
  193. get
  194. {
  195. return this.maxDropDownItems;
  196. }
  197. set
  198. {
  199. if ((value < 1) || (value > 100))
  200. {
  201. throw new ArgumentOutOfRangeException("MaxDropDownItems must be between 1 and 100");
  202. }
  203. this.maxDropDownItems = value;
  204. }
  205. }
  206. /// <summary>
  207. /// Gets or sets a value indicating whether your code or the operating
  208. /// system will handle drawing of elements in the list
  209. /// </summary>
  210. public DrawMode DrawMode
  211. {
  212. get
  213. {
  214. return this.listbox.DrawMode;
  215. }
  216. set
  217. {
  218. if (!Enum.IsDefined(typeof(DrawMode), value))
  219. {
  220. throw new InvalidEnumArgumentException("value", (int) value, typeof(DrawMode));
  221. }
  222. this.listbox.DrawMode = value;
  223. }
  224. }
  225. /// <summary>
  226. /// Gets or sets a value indicating whether the drop-down portion of the
  227. /// editor should resize to avoid showing partial items
  228. /// </summary>
  229. public bool IntegralHeight
  230. {
  231. get
  232. {
  233. return this.listbox.IntegralHeight;
  234. }
  235. set
  236. {
  237. this.listbox.IntegralHeight = value;
  238. }
  239. }
  240. /// <summary>
  241. /// Gets or sets the height of an item in the editor
  242. /// </summary>
  243. public int ItemHeight
  244. {
  245. get
  246. {
  247. return this.listbox.ItemHeight;
  248. }
  249. set
  250. {
  251. this.listbox.ItemHeight = value;
  252. }
  253. }
  254. /// <summary>
  255. /// Gets an object representing the collection of the items contained
  256. /// in this ComboBoxCellEditor
  257. /// </summary>
  258. public ListBox.ObjectCollection Items
  259. {
  260. get
  261. {
  262. return this.listbox.Items;
  263. }
  264. }
  265. /// <summary>
  266. /// Gets or sets the maximum number of characters allowed in the editable
  267. /// portion of a ComboBoxCellEditor
  268. /// </summary>
  269. public int MaxLength
  270. {
  271. get
  272. {
  273. return this.TextBox.MaxLength;
  274. }
  275. set
  276. {
  277. this.TextBox.MaxLength = value;
  278. }
  279. }
  280. /// <summary>
  281. /// Gets or sets the index specifying the currently selected item
  282. /// </summary>
  283. public int SelectedIndex
  284. {
  285. get
  286. {
  287. return this.listbox.SelectedIndex;
  288. }
  289. set
  290. {
  291. this.listbox.SelectedIndex = value;
  292. }
  293. }
  294. /// <summary>
  295. /// Gets or sets currently selected item in the ComboBoxCellEditor
  296. /// </summary>
  297. public object SelectedItem
  298. {
  299. get
  300. {
  301. return this.listbox.SelectedItem;
  302. }
  303. set
  304. {
  305. this.listbox.SelectedItem = value;
  306. }
  307. }
  308. #endregion
  309. #region Events
  310. /// <summary>
  311. /// Handler for the editors TextBox.KeyDown and ListBox.KeyDown events
  312. /// </summary>
  313. /// <param name="sender">The object that raised the event</param>
  314. /// <param name="e">A KeyEventArgs that contains the event data</param>
  315. protected virtual void OnKeyDown(object sender, KeyEventArgs e)
  316. {
  317. if (e.KeyData == Keys.Up)
  318. {
  319. int index = this.SelectedIndex;
  320. if (index == -1)
  321. {
  322. this.SelectedIndex = 0;
  323. }
  324. else if (index > 0)
  325. {
  326. this.SelectedIndex--;
  327. }
  328. e.Handled = true;
  329. }
  330. else if (e.KeyData == Keys.Down)
  331. {
  332. int index = this.SelectedIndex;
  333. if (index == -1)
  334. {
  335. this.SelectedIndex = 0;
  336. }
  337. else if (index < this.Items.Count - 1)
  338. {
  339. this.SelectedIndex++;
  340. }
  341. e.Handled = true;
  342. }
  343. }
  344. /// <summary>
  345. /// Handler for the editors TextBox.MouseWheel event
  346. /// </summary>
  347. /// <param name="sender">The object that raised the event</param>
  348. /// <param name="e">A MouseEventArgs that contains the event data</param>
  349. protected virtual void OnMouseWheel(object sender, MouseEventArgs e)
  350. {
  351. int index = this.SelectedIndex;
  352. if (index == -1)
  353. {
  354. this.SelectedIndex = 0;
  355. }
  356. else
  357. {
  358. if (e.Delta > 0)
  359. {
  360. if (index > 0)
  361. {
  362. this.SelectedIndex--;
  363. }
  364. }
  365. else
  366. {
  367. if (index < this.Items.Count - 1)
  368. {
  369. this.SelectedIndex++;
  370. }
  371. }
  372. }
  373. }
  374. /// <summary>
  375. /// Raises the DrawItem event
  376. /// </summary>
  377. /// <param name="e">A DrawItemEventArgs that contains the event data</param>
  378. protected virtual void OnDrawItem(DrawItemEventArgs e)
  379. {
  380. if (DrawItem != null)
  381. {
  382. DrawItem(this, e);
  383. }
  384. }
  385. /// <summary>
  386. /// Raises the MeasureItem event
  387. /// </summary>
  388. /// <param name="e">A MeasureItemEventArgs that contains the event data</param>
  389. protected virtual void OnMeasureItem(MeasureItemEventArgs e)
  390. {
  391. if (MeasureItem != null)
  392. {
  393. MeasureItem(this, e);
  394. }
  395. }
  396. /// <summary>
  397. /// Raises the SelectedIndexChanged event
  398. /// </summary>
  399. /// <param name="e">An EventArgs that contains the event data</param>
  400. protected virtual void OnSelectedIndexChanged(EventArgs e)
  401. {
  402. if (SelectedIndexChanged != null)
  403. {
  404. SelectedIndexChanged(this, e);
  405. }
  406. this.TextBox.Text = this.SelectedItem.ToString();
  407. }
  408. /// <summary>
  409. /// Handler for the editors ListBox.Click event
  410. /// </summary>
  411. /// <param name="sender">The object that raised the event</param>
  412. /// <param name="e">An EventArgs that contains the event data</param>
  413. private void listbox_Click(object sender, EventArgs e)
  414. {
  415. this.DroppedDown = false;
  416. this.EditingTable.StopEditing();
  417. }
  418. /// <summary>
  419. /// Handler for the editors ListBox.SelectedIndexChanged event
  420. /// </summary>
  421. /// <param name="sender">The object that raised the event</param>
  422. /// <param name="e">An EventArgs that contains the event data</param>
  423. private void listbox_SelectedIndexChanged(object sender, EventArgs e)
  424. {
  425. this.OnSelectedIndexChanged(e);
  426. }
  427. /// <summary>
  428. /// Handler for the editors ListBox.MouseEnter event
  429. /// </summary>
  430. /// <param name="sender">The object that raised the event</param>
  431. /// <param name="e">An EventArgs that contains the event data</param>
  432. private void listbox_MouseEnter(object sender, EventArgs e)
  433. {
  434. this.EditingTable.RaiseCellMouseLeave(this.EditingCellPos);
  435. }
  436. /// <summary>
  437. /// Handler for the editors ListBox.DrawItem event
  438. /// </summary>
  439. /// <param name="sender">The object that raised the event</param>
  440. /// <param name="e">A DrawItemEventArgs that contains the event data</param>
  441. private void listbox_DrawItem(object sender, DrawItemEventArgs e)
  442. {
  443. this.OnDrawItem(e);
  444. }
  445. /// <summary>
  446. /// Handler for the editors ListBox.MeasureItem event
  447. /// </summary>
  448. /// <param name="sender">The object that raised the event</param>
  449. /// <param name="e">A MeasureItemEventArgs that contains the event data</param>
  450. private void listbox_MeasureItem(object sender, MeasureItemEventArgs e)
  451. {
  452. this.OnMeasureItem(e);
  453. }
  454. #endregion
  455. }
  456. }