C_TXT_DropDownList.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  1. /*******************************************************************************
  2. * Copyright(c) 2014 DongkeSoft All rights reserved. / Confidential
  3. * 类的信息:
  4. * 1.程序名称:C_TXT_DropDownList.cs
  5. * 2.功能描述:扩展的控件
  6. * 编辑履历:
  7. * 作者 日期 版本 修改内容
  8. * 陈晓野 2014/09/29 1.00 新建
  9. *******************************************************************************/
  10. using Dongke.IBOSS.PRD.Basics.Library;
  11. using System;
  12. using System.ComponentModel;
  13. using System.Data;
  14. using System.Drawing;
  15. using System.Windows.Forms;
  16. namespace Dongke.IBOSS.PRD.Basics.BaseControls
  17. {
  18. public partial class C_TXT_DropDownList : DKTextBoxBase
  19. {
  20. #region 成员变量
  21. public ListBox _lstShowChoice = null; // 弹出的选择下拉选项
  22. private Color _lstForeColor = Color.Gray; // 弹出的选择下拉选项前景色
  23. private Color _lstBackColor = Color.Snow; // 弹出的选择下拉选项背景色
  24. private DataTable _dataSource; // 本控件的数据源
  25. private string _displayMember; // 控件下拉选择项显示的属性
  26. private string _valueMember; // 控件下拉选择项实际值的属性
  27. private bool _allowSpace = true; // 是否允许输入空格
  28. private bool _dropDownOnly = true; // 只能从下拉选项中选择值
  29. public int _originalLocation = 0; // 光标原来的位置
  30. public string _originalText = ""; // 文本框原来的文本值
  31. public bool _isKeyDown = false; // 是否按下了键盘
  32. private object _selectedValue = ""; // 下拉选择选中的值
  33. private object _selectedItem = "";
  34. private bool _IsOnlyShowValid = true; // 是否只显示有效数据
  35. private bool _isSetPosition = true;
  36. #endregion
  37. public C_TXT_DropDownList()
  38. {
  39. InitializeComponent();
  40. IsSetPosition = false;
  41. this.Leave += new EventHandler(dkDropDownList_Leave);
  42. this.KeyDown += new KeyEventHandler(dkDropDownList_KeyDown);
  43. this.KeyUp += new KeyEventHandler(dkDropDownList_KeyUp);
  44. this.DoubleClick += new EventHandler(dkDropDownList_DoubleClick);
  45. }
  46. public C_TXT_DropDownList(IContainer container)
  47. {
  48. container.Add(this);
  49. InitializeComponent();
  50. this.Leave += new EventHandler(dkDropDownList_Leave);
  51. this.KeyDown += new KeyEventHandler(dkDropDownList_KeyDown);
  52. this.KeyUp += new KeyEventHandler(dkDropDownList_KeyUp);
  53. this.DoubleClick += new EventHandler(dkDropDownList_DoubleClick);
  54. }
  55. #region 公开属性
  56. /// <summary>
  57. /// 设定或者取得本控件的数据源
  58. /// </summary>
  59. [Description("设定或者取得本控件的数据源")]
  60. public DataTable DataSource
  61. {
  62. get
  63. {
  64. return _dataSource;
  65. }
  66. set
  67. {
  68. _dataSource = (DataTable)SetFilter(value);
  69. ListBox lstBox = this.lstPrompt;
  70. if (lstBox != null)
  71. {
  72. SetParentBySummary();
  73. lstBox.DataSource = _dataSource;
  74. lstBox.DisplayMember = _displayMember;
  75. lstBox.ValueMember = _valueMember;
  76. }
  77. }
  78. }
  79. /// <summary>
  80. /// 设定或者获取控件是否可以输入空格
  81. /// </summary>
  82. [Description("设定或者获取控件是否可以输入空格")]
  83. [DefaultValue(true)]
  84. public bool AllowSpace
  85. {
  86. get
  87. {
  88. return _allowSpace;
  89. }
  90. set
  91. {
  92. _allowSpace = value;
  93. }
  94. }
  95. /// <summary>
  96. /// 设定或者获取控件是否只能从下拉选项中选择值
  97. /// </summary>
  98. [Description("设定或者获取控件是否只能从下拉选项中选择值")]
  99. [DefaultValue(true)]
  100. public bool DropDownOnly
  101. {
  102. get
  103. {
  104. return _dropDownOnly;
  105. }
  106. set
  107. {
  108. _dropDownOnly = value;
  109. }
  110. }
  111. /// <summary>
  112. /// 指示要为下拉选择项显示的属性
  113. /// </summary>
  114. [Description("指示要为下拉选择项显示的属性")]
  115. public string DisplayMember
  116. {
  117. get
  118. {
  119. return _displayMember;
  120. }
  121. set
  122. {
  123. _displayMember = value;
  124. }
  125. }
  126. /// <summary>
  127. /// 指示要为下拉选择项实际值的属性
  128. /// </summary>
  129. [Description("指示要为下拉选择项实际值的属性")]
  130. public string ValueMember
  131. {
  132. get
  133. {
  134. return _valueMember;
  135. }
  136. set
  137. {
  138. _valueMember = value;
  139. }
  140. }
  141. /// <summary>
  142. /// 控件的值
  143. /// </summary>
  144. [Description("取得和设定与控件关联的值,即valueMember对应的值")]
  145. public object SelectedValue
  146. {
  147. get
  148. {
  149. return _selectedValue;
  150. }
  151. set
  152. {
  153. _selectedValue = value;
  154. if (string.IsNullOrEmpty(value + ""))
  155. {
  156. this.Text = string.Empty;
  157. }
  158. if (_selectedValue != null && _selectedValue.ToString() != "" && this.DataSource != null)
  159. {
  160. DataTable tempTable = this.DataSource.Copy();
  161. DataRow[] dataRows = tempTable.Select(ValueMember.ToUpper() + " = '" + this._selectedValue + "'");
  162. if (dataRows.Length == 1)
  163. {
  164. this.Text = dataRows[0][DisplayMember] as string;
  165. }
  166. }
  167. }
  168. }
  169. /// <summary>
  170. /// 重新设置位置
  171. /// </summary>
  172. [DefaultValue(true)]
  173. public bool IsSetPosition
  174. {
  175. set
  176. {
  177. _isSetPosition = value;
  178. }
  179. get
  180. {
  181. return _isSetPosition;
  182. }
  183. }
  184. /// <summary>
  185. /// 是否只显示有效数据
  186. /// </summary>
  187. [Description("设置控件是否只显示有效数据。")]
  188. [DefaultValue(true)]
  189. public bool IsOnlyShowValid
  190. {
  191. get
  192. {
  193. return _IsOnlyShowValid;
  194. }
  195. set
  196. {
  197. _IsOnlyShowValid = value;
  198. }
  199. }
  200. public ListBox lstPrompt
  201. {
  202. get
  203. {
  204. //如果没有列表用于显示提示的列表框,则创建一个
  205. if ((_lstShowChoice == null) && this.Parent != null)
  206. {
  207. _lstShowChoice = new ListBox();
  208. _lstShowChoice.Visible = false;//false
  209. _lstShowChoice.Left = this.Left;
  210. _lstShowChoice.Top = this.Bottom;
  211. _lstShowChoice.Width = this.Width;
  212. _lstShowChoice.TabStop = false;
  213. _lstShowChoice.Sorted = true;
  214. _lstShowChoice.ForeColor = this._lstForeColor; // 前景色
  215. _lstShowChoice.BackColor = this._lstBackColor; // 背景色
  216. _lstShowChoice.BorderStyle = BorderStyle.FixedSingle;
  217. IsSetPosition = false;
  218. //如果提示框过低,则显示到上面
  219. if (_lstShowChoice.Bottom > this.Parent.Height)
  220. {
  221. _lstShowChoice.Top = this.Top - _lstShowChoice.Height + 8;
  222. }
  223. if (!IsSetPosition)
  224. {
  225. this.Parent.Controls.Add(_lstShowChoice);
  226. this.Parent.ResumeLayout(false);
  227. //this.Controls.Add(_lstShowChoice);
  228. //this.ResumeLayout(false);
  229. }
  230. // 注册鼠标移动、点击事件
  231. _lstShowChoice.MouseUp += new MouseEventHandler(lstBox_MouseUp);
  232. _lstShowChoice.MouseMove += new MouseEventHandler(lstBox_MouseMove);
  233. //this.Parent.Controls.Add(_lstShowChoice);
  234. //this.Parent.ResumeLayout(false);
  235. _lstShowChoice.BringToFront();
  236. }
  237. return _lstShowChoice;
  238. }
  239. }
  240. //void _lstShowChoice_DrawItem(object sender, DrawItemEventArgs e)
  241. //{
  242. // _lstShowChoice.DrawMode = DrawMode.OwnerDrawFixed;
  243. // e.DrawBackground();
  244. // Brush myBrush = Brushes.Black;
  245. // FontFamily fontFamily = new FontFamily("宋体");
  246. // System.Drawing.Font myFont = new Font(fontFamily,10);
  247. // if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
  248. // {
  249. // //e.Graphics.FillRectangle(Brushes.Blue, e.Bounds);
  250. // if (e.Index > -1)
  251. // {
  252. // e.Graphics.DrawString(_lstShowChoice.Items[e.Index].ToString(), myFont, Brushes.White, e.Bounds, StringFormat.GenericDefault);
  253. // }
  254. // }
  255. // else
  256. // {
  257. // //e.Graphics.FillRectangle(Brushes.White, e.Bounds);
  258. // if (e.Index > -1)
  259. // {
  260. // e.Graphics.DrawString(_lstShowChoice.Items[e.Index].ToString(), myFont, myBrush, e.Bounds, StringFormat.GenericDefault);
  261. // }
  262. // }
  263. // e.DrawFocusRectangle();
  264. //}
  265. /// <summary>
  266. /// 弹出的选择下拉选项前景色
  267. /// </summary>
  268. [Description("取得和设定弹出的选择下拉选项前景色")]
  269. public Color PromptForeColor
  270. {
  271. get
  272. {
  273. return _lstForeColor;
  274. }
  275. set
  276. {
  277. _lstForeColor = value;
  278. ListBox lstBox = this.lstPrompt;
  279. SetParentBySummary();
  280. if (lstBox != null)
  281. {
  282. lstBox.ForeColor = _lstForeColor;
  283. }
  284. }
  285. }
  286. /// <summary>
  287. /// 弹出的选择下拉选项背景色
  288. /// </summary>
  289. [Description("取得和设定弹出的选择下拉选项背景色")]
  290. public Color PromptBackColor
  291. {
  292. get
  293. {
  294. return _lstBackColor;
  295. }
  296. set
  297. {
  298. _lstBackColor = value;
  299. ListBox lstBox = this.lstPrompt;
  300. if (lstBox != null)
  301. {
  302. SetParentBySummary();
  303. lstBox.BackColor = _lstBackColor;
  304. }
  305. }
  306. }
  307. #endregion
  308. #region 私有方法或者函数
  309. /// <summary>
  310. /// 鼠标点击下拉选择项时,选中处理
  311. /// </summary>
  312. /// <param name="sender"></param>
  313. /// <param name="e"></param>
  314. private void lstBox_MouseUp(object sender, MouseEventArgs e)
  315. {
  316. if (_selectedItem != null)
  317. {
  318. DataRowView dataRowView = _selectedItem as DataRowView;
  319. if (dataRowView != null)
  320. {
  321. this.Text = dataRowView[_displayMember].ToString();
  322. this._selectedValue = dataRowView[_valueMember].ToString();
  323. }
  324. this.SelectionStart = this.Text.Length;
  325. //选择后文本框失去了焦点,这里移回来
  326. this.Focus();
  327. }
  328. }
  329. /// <summary>
  330. /// 鼠标经过下拉选择项时,选中处理
  331. /// </summary>
  332. /// <param name="sender"></param>
  333. /// <param name="e"></param>
  334. private void lstBox_MouseMove(object sender, MouseEventArgs e)
  335. {
  336. ListBox lstBox = (ListBox)sender;
  337. Point point = new Point(e.X, e.Y);
  338. int n = lstBox.IndexFromPoint(point);
  339. if (n >= 0)
  340. {
  341. lstBox.SelectedIndex = n;
  342. _selectedItem = lstBox.SelectedItem;
  343. }
  344. }
  345. /// <summary>
  346. /// 在本控件中按下了键盘的任何键
  347. /// </summary>
  348. /// <param name="sender"></param>
  349. /// <param name="e"></param>
  350. private void dkDropDownList_KeyDown(object sender, KeyEventArgs e)
  351. {
  352. //_lstShowChoice.Visible = true;
  353. if (_lstShowChoice != null)
  354. {
  355. _lstShowChoice.Visible = true;
  356. }
  357. _originalLocation = this.SelectionStart;
  358. _isKeyDown = true;
  359. _originalText = this.Text;
  360. }
  361. /// <summary>
  362. /// 在本控件中按下了键盘的任何键,进行匹配处理
  363. /// </summary>
  364. /// <param name="sender"></param>
  365. /// <param name="e"></param>
  366. private void dkDropDownList_KeyUp(object sender, KeyEventArgs e)
  367. {
  368. if (!_isKeyDown)
  369. {
  370. return;
  371. }
  372. // 将按下键标识置回原始状态
  373. _isKeyDown = false;
  374. ListBox lstBox = this.lstPrompt;
  375. //SetParentBySummary();
  376. switch (e.KeyCode)
  377. {
  378. // 通过上下箭头在待选框中移动
  379. case Keys.Up:
  380. case Keys.Down:
  381. if ((lstBox != null) && !this.Multiline) // 多行文本通过上下箭头在两行之间移动
  382. {
  383. if ((e.KeyCode == Keys.Up) && (lstBox.SelectedIndex > -1)) // ↑
  384. {
  385. lstBox.SelectedIndex--;
  386. }
  387. else if ((e.KeyCode == Keys.Down) && (lstBox.SelectedIndex < lstBox.Items.Count - 1)) //↑
  388. {
  389. lstBox.SelectedIndex++;
  390. }
  391. //上下箭头不能移动当前光标,因此,还原原来位置
  392. this.SelectionStart = _originalLocation;
  393. //显示提示框
  394. if (!lstBox.Visible)
  395. {
  396. if (lstBox.Width != this.Width)
  397. {
  398. lstBox.Width = this.Width;
  399. }
  400. lstBox.Visible = true;
  401. }
  402. }
  403. break;
  404. case Keys.Escape: // ESC隐藏提示
  405. this.Text = string.Empty;
  406. this._selectedValue = string.Empty;
  407. if ((lstBox != null) && lstBox.Visible)
  408. {
  409. lstBox.Hide();
  410. }
  411. break;
  412. case Keys.Return: // 回车选择一个或跳到下一控件
  413. if ((lstBox == null) || this.Multiline)
  414. {
  415. break;
  416. }
  417. // 没有显示提示框时,移动到下一控件
  418. if (!lstBox.Visible)
  419. {
  420. SendKeys.Send("{TAB}");
  421. }
  422. else // 有提示,关闭提示
  423. {
  424. if (lstBox.SelectedIndex > -1) // 有选择,使用当前选择的内容
  425. {
  426. DataRowView dataRowView = lstBox.SelectedItem as DataRowView;
  427. if (dataRowView != null)
  428. {
  429. this.Text = dataRowView[_displayMember].ToString();
  430. this._selectedValue = dataRowView[_valueMember].ToString();
  431. }
  432. }
  433. this.SelectionStart = this.Text.Length;
  434. this.SelectAll();
  435. lstBox.Hide();
  436. }
  437. break;
  438. // 按delete键清空
  439. case Keys.Delete:
  440. this.Text = string.Empty;
  441. this._selectedValue = string.Empty;
  442. if ((lstBox != null) && lstBox.Visible)
  443. {
  444. lstBox.Hide();
  445. }
  446. break;
  447. default: // 判断文本是否改变
  448. string textString = this.Text;
  449. // 不允许产生空格,去掉文本中的空格
  450. if (!this.AllowSpace)
  451. {
  452. textString = this.Text.Replace(" ", "");
  453. }
  454. int nStart = this.SelectionStart;
  455. if (textString != _originalText) // 文本有改变
  456. {
  457. // 设置当前文本和键盘光标位置
  458. this.Text = textString;
  459. if (nStart > this.Text.Length)
  460. {
  461. nStart = this.Text.Length;
  462. }
  463. this.SelectionStart = nStart;
  464. //修改可供选择的内容,并显示供选择的列表框
  465. if (lstBox != null)
  466. {
  467. FillPrompt(textString);
  468. if (!lstBox.Visible)
  469. {
  470. if (lstBox.Width != this.Width)
  471. {
  472. lstBox.Width = this.Width;
  473. }
  474. lstBox.Visible = true;
  475. }
  476. }
  477. }
  478. break;
  479. }
  480. }
  481. /// <summary>
  482. /// 为下拉选择赋值
  483. /// </summary>
  484. /// <param name="searchText">匹配内容</param>
  485. private void FillPrompt(string searchText)
  486. {
  487. //return;
  488. ListBox lstBox = this.lstPrompt;
  489. if (lstBox != null && _dataSource != null)
  490. {
  491. SetParentBySummary();
  492. //BY 赵含 编号:C帐套补充一览105、106
  493. // string filter = DisplayMember + " LIKE '%" + Utility.SelectFilterLike(searchText) + "%'";
  494. //string filter = Utility.SelectFilterLike(searchText);
  495. string filter = DisplayMember + " LIKE '%" + (Utility.SelectFilterLike(this.Text)).Replace(@"*", @"[*]") + "%'";
  496. // string filter = DisplayMember + " LIKE '%" + searchText + "%'";
  497. _dataSource.DefaultView.RowFilter = filter;
  498. DataTable returnTable = _dataSource.DefaultView.ToTable();
  499. lstBox.DataSource = returnTable;
  500. lstBox.Refresh();
  501. _selectedItem = lstBox.SelectedItem;
  502. }
  503. }
  504. /// <summary>
  505. /// 下拉选择项失去焦点处理
  506. /// </summary>
  507. /// <param name="sender"></param>
  508. /// <param name="e"></param>
  509. private void dkDropDownList_Leave(object sender, EventArgs e)
  510. {
  511. //return;
  512. ListBox lstBox = this.lstPrompt;
  513. // 对于只选字段,必须输入同待选相匹配的值
  514. if (this.DropDownOnly && _dataSource != null)
  515. {
  516. //BY 赵含 编号:C帐套补充一览105、106
  517. //string filter = DisplayMember + " LIKE '%" + Utility.SelectFilterLike(this.Text) + "%'";
  518. string filter = DisplayMember + " LIKE '%" + (Utility.SelectFilterLike(this.Text)).Replace(@"*", @"[*]") + "%'";
  519. _dataSource.DefaultView.RowFilter = filter;
  520. DataTable returnTable = _dataSource.DefaultView.ToTable();
  521. if (returnTable.Rows.Count > 0)
  522. {
  523. DataRowView dataRowView = _selectedItem as DataRowView;
  524. if (lstBox != null && lstBox.Visible)
  525. {
  526. if (dataRowView != null)
  527. {
  528. this.Text = dataRowView[DisplayMember] + "";
  529. this._selectedValue = dataRowView[ValueMember] + "";
  530. }
  531. else
  532. {
  533. this.Text = returnTable.Rows[0][DisplayMember] + "";
  534. this._selectedValue = returnTable.Rows[0][ValueMember];
  535. }
  536. }
  537. else
  538. {
  539. //this.Text = "";
  540. //this._selectedValue = null;
  541. }
  542. }
  543. else
  544. {
  545. this.Text = "";
  546. this._selectedValue = null;
  547. }
  548. }
  549. // 失去焦点后,必须隐藏提示
  550. lstBox = this.lstPrompt;
  551. if (lstBox != null)
  552. {
  553. lstBox.Visible = false;
  554. }
  555. }
  556. /// <summary>
  557. /// 本控件双击事件
  558. /// </summary>
  559. /// <param name="sender"></param>
  560. /// <param name="e"></param>
  561. private void dkDropDownList_DoubleClick(object sender, EventArgs e)
  562. {
  563. if (this.ReadOnly || !this.Enabled)
  564. {
  565. return;
  566. }
  567. ListBox lstBox = this.lstPrompt;
  568. FillPrompt(this.Text);
  569. if ((lstBox != null) && (!lstBox.Visible))
  570. {
  571. SetParentBySummary();
  572. if (lstBox.Width != this.Width)
  573. {
  574. lstBox.Width = this.Width;
  575. }
  576. lstBox.Visible = true;
  577. }
  578. }
  579. /// <summary>
  580. /// 过滤数据源
  581. /// </summary>
  582. /// <param name="dataSource"></param>
  583. /// <returns></returns>
  584. protected object SetFilter(object dataSource)
  585. {
  586. //string filter = "ValueFlag = 1";
  587. if (dataSource is BindingSource)
  588. {
  589. BindingSource bSource = (BindingSource)dataSource;
  590. // 若设置了只显示有效数据
  591. if (this._IsOnlyShowValid == true)
  592. {
  593. //bSource.Filter = filter;
  594. }
  595. dataSource = bSource;
  596. }
  597. else if (dataSource is DataTable)
  598. {
  599. DataTable dtbl = (DataTable)dataSource;
  600. // 若设置了只显示有效数据
  601. if (this._IsOnlyShowValid == true)
  602. {
  603. //dtbl.DefaultView.RowFilter = filter;
  604. }
  605. dataSource = dtbl.DefaultView.ToTable();
  606. }
  607. return dataSource;
  608. }
  609. /// <summary>
  610. /// 科目汇总时使用
  611. /// </summary>
  612. private void SetParentBySummary()
  613. {
  614. // 周兴 2018-4-7 注释
  615. //if (this.Parent != null && IsSetPosition)
  616. if (this.Parent != null)
  617. {
  618. _lstShowChoice.Left = this.Left + this.Parent.Left;
  619. _lstShowChoice.Top = this.Bottom + this.Parent.Top;
  620. Control control = this.Parent.Parent;
  621. if (control != null)
  622. {
  623. control.Controls.Add(_lstShowChoice);
  624. control.ResumeLayout(false);
  625. _lstShowChoice.BringToFront();
  626. }
  627. }
  628. }
  629. #endregion
  630. }
  631. }