You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

703 lines
23 KiB

  1. #if NETFX || NETCORE
  2. using System;
  3. using System.Collections.Generic;
  4. using System.ComponentModel;
  5. using System.Drawing;
  6. using System.Data;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. namespace Apewer.Surface
  10. {
  11. /// <summary>
  12. ///
  13. /// </summary>
  14. public partial class BlockText : BaseControl
  15. {
  16. private const string modeinput = "input";
  17. private const string moderadio = "radio";
  18. private const string modecombo = "combo";
  19. // private bool _lonely = false;
  20. private bool _delemiter = false;
  21. private bool _statehover = false, _statefocus = false;
  22. private bool _busy = false;
  23. private string _mode = modeinput;
  24. // private Panel _body = new Panel();
  25. private Panel _left = new Panel();
  26. // private Panel _middle = new Panel();
  27. private Panel _right = new Panel();
  28. private BlockLabel _label = new BlockLabel();
  29. private TextBox _input = new TextBox();
  30. private ComboBox _combo = new ComboBox();
  31. private int _radiowidth = 80;
  32. private List<BlockButton> _radio = new List<BlockButton>();
  33. private List<string> _value = new List<string>();
  34. private List<string> _alias = new List<string>();
  35. private List<Color> _color = new List<Color>();
  36. private string _text = "";
  37. #region this
  38. /// <summary></summary>
  39. private void VarInit()
  40. {
  41. _label.Text = "Caption";
  42. _input.Text = Name;
  43. }
  44. /// <summary></summary>
  45. public BlockText()
  46. {
  47. this.Size = new Size(300, 40);
  48. VarInit();
  49. ControlInit();
  50. ControlAdjust();
  51. EventInit();
  52. GoColor();
  53. GoInput();
  54. }
  55. /// <summary></summary>
  56. public new void Dispose()
  57. {
  58. if (_left != null) _left.Dispose();
  59. if (_right != null) _right.Dispose();
  60. if (_label != null) _label.Dispose();
  61. if (_input != null) _input.Dispose();
  62. base.Dispose();
  63. }
  64. #endregion
  65. #region surface
  66. /// <summary></summary>
  67. private void ControlInit()
  68. {
  69. this.Controls.Add(_left);
  70. this.Controls.Add(_right);
  71. _left.Controls.Add(_label);
  72. _right.Controls.Add(_input);
  73. _right.Controls.Add(_combo);
  74. this.Padding = new Padding(1);
  75. _left.Dock = DockStyle.Left;
  76. _left.Padding = new Padding(8, 0, 8, 0);
  77. _left.Width = 100;
  78. _label.Dock = DockStyle.Fill;
  79. _label.TextAlign = ContentAlignment.MiddleCenter;
  80. _right.Dock = DockStyle.Right;
  81. _input.BorderStyle = BorderStyle.None;
  82. _input.Font = FormsUtility.DefaultFont;
  83. _combo.TabStop = false;
  84. _combo.FlatStyle = FlatStyle.Flat;
  85. _combo.Dock = DockStyle.Right;
  86. _combo.ItemHeight = Height - 8;
  87. _combo.MaxDropDownItems = 10;
  88. _combo.DrawMode = DrawMode.OwnerDrawVariable;
  89. _combo.DropDownStyle = ComboBoxStyle.DropDownList;
  90. }
  91. /// <summary></summary>
  92. private void ControlAdjust()
  93. {
  94. if ((this.Width > 0) && (this.Height > 0))
  95. {
  96. var vfontoffset = FormsUtility.MsyhExist ? 0 : 2;
  97. //var vshowcombo = (_combo.Items.Count > 0);
  98. _right.Width = Width - Padding.Left - Padding.Right - _left.Width - (_delemiter ? 1 : 0);
  99. switch (_mode)
  100. {
  101. case modeinput:
  102. _input.Height = 14;
  103. _input.Width = _right.Width - 18;
  104. _input.Left = 12;
  105. _input.Top = (_right.Height - 14) / 2 - 1 + vfontoffset;
  106. break;
  107. case moderadio:
  108. for (int i = 0; i < _radio.Count; i++)
  109. {
  110. _radio[i].Left = RadioWidth * i;
  111. _radio[i].Top = 3;
  112. _radio[i].Width = RadioWidth;
  113. _radio[i].Height = this.Height - 8;
  114. }
  115. break;
  116. case modecombo:
  117. _combo.Width = _right.Width;
  118. break;
  119. }
  120. }
  121. }
  122. /// <summary></summary>
  123. private void GoColor()
  124. {
  125. if (_statefocus)
  126. {
  127. this.BackColor = _focusborder;
  128. _left.BackColor = _focusleft;
  129. _left.ForeColor = _focuscaption;
  130. _right.BackColor = _focusright;
  131. _label.ForeColor = _focuscaption;
  132. _input.ForeColor = Locked ? _label.ForeColor : _focustext;
  133. // _middle.BackColor = _left.BackColor; // this.BackColor;
  134. }
  135. else
  136. {
  137. if (_statehover)
  138. {
  139. this.BackColor = _hoverborder;
  140. _left.BackColor = _hoverleft;
  141. _left.ForeColor = _hovercaption;
  142. _right.BackColor = _hoverright;
  143. _label.ForeColor = _hovercaption;
  144. _input.ForeColor = Locked ? _label.ForeColor : _hovertext;
  145. // _middle.BackColor = _left.BackColor;
  146. }
  147. else
  148. {
  149. this.BackColor = _normalborder;
  150. _left.BackColor = _normalleft;
  151. _left.ForeColor = _normalcaption;
  152. _right.BackColor = _normalright;
  153. _label.ForeColor = _normalcaption;
  154. _input.ForeColor = Locked ? _label.ForeColor : _normaltext;
  155. // _middle.BackColor = _left.BackColor;
  156. }
  157. }
  158. _input.BackColor = _right.BackColor;
  159. }
  160. /// <summary>设置样式为候选项。</summary>
  161. private void GoCandidate(BlockButton button)
  162. {
  163. button.NormalBorder = FormsUtility.White;
  164. button.NormalText = FormsUtility.GraceSilver;
  165. button.HoverBorder = FormsUtility.GraceWall;
  166. button.HoverText = FormsUtility.Gray;
  167. }
  168. /// <summary>设置样式为当前项。</summary>
  169. private void GoCurrent(BlockButton button)
  170. {
  171. button.NormalBorder = FormsUtility.GraceSilver;
  172. button.NormalText = Color.Black;
  173. button.HoverBorder = FormsUtility.GraceSilver;
  174. button.HoverText = Color.Black;
  175. }
  176. #endregion
  177. #region accessor
  178. /// <summary></summary>
  179. public event EventHandler Changed;
  180. /// <summary></summary>
  181. public bool Busy { get { return _busy; } private set { _busy = false; } }
  182. /// <summary></summary>
  183. public int RadioWidth
  184. {
  185. get { return _radiowidth; }
  186. set { _radiowidth = (value >= 0) ? value : 0; }
  187. }
  188. /// <summary>添加选项。</summary>
  189. /// <param name="value">选项值。</param>
  190. public void Add(string value)
  191. {
  192. Add(value, value, Color.Black);
  193. }
  194. /// <summary>添加选项。</summary>
  195. /// <param name="value">选项值。</param>
  196. /// <param name="color">文字颜色。</param>
  197. private void Add(string value, Color color)
  198. {
  199. Add(value, value, color);
  200. }
  201. /// <summary>添加选项。</summary>
  202. /// <param name="value">选项值。</param>
  203. /// <param name="alias">显示名称。</param>
  204. public void Add(string value, string alias)
  205. {
  206. Add(value, alias, Color.Black);
  207. }
  208. /// <summary>添加选项。</summary>
  209. /// <param name="value">选项值。</param>
  210. /// <param name="alias">显示名称。</param>
  211. /// <param name="color">文字颜色。</param>
  212. private void Add(string value, string alias, Color color)
  213. {
  214. if (value != null)
  215. {
  216. var v = string.IsNullOrEmpty(value) ? "" : value;
  217. var a = string.IsNullOrEmpty(alias) ? v : alias;
  218. var c = (color == null) ? Color.Black : color;
  219. _value.Add(v);
  220. _alias.Add(a);
  221. _color.Add(c);
  222. // combo
  223. _combo.Items.Add(a);
  224. // radio
  225. _radio.Add(new BlockButton());
  226. var index = _alias.Count - 1;
  227. _radio[index].Caption = _alias[index];
  228. _radio[index].Tag = value;
  229. _radio[index].BodyMargin = new Padding(1);
  230. _radio[index].MouseDown += Event_Radio_MouseDown;
  231. _radio[index].MouseMove += Event_Caption_MouseMove;
  232. _radio[index].MouseLeave += Event_Caption_MouseLeave;
  233. if (_mode != moderadio) _radio[index].Visible = false;
  234. _right.Controls.Add(_radio[index]);
  235. GoCandidate(_radio[index]);
  236. ControlAdjust();
  237. }
  238. }
  239. /// <summary>清除所有选项。</summary>
  240. public void Clean()
  241. {
  242. Clear();
  243. }
  244. /// <summary>清除所有选项。</summary>
  245. public void Clear()
  246. {
  247. _value.Clear();
  248. _alias.Clear();
  249. _color.Clear();
  250. _combo.Items.Clear();
  251. ControlAdjust();
  252. }
  253. /// <summary>切换到单选模式。</summary>
  254. public void GoRadio()
  255. {
  256. if (_mode == modeinput) _text = _input.Text;
  257. _mode = moderadio;
  258. _input.Visible = false;
  259. _combo.Visible = false;
  260. foreach (var vi in _radio) vi.Visible = true;
  261. ControlAdjust();
  262. }
  263. /// <summary>切换到输入模式。</summary>
  264. public void GoInput()
  265. {
  266. _input.Visible = true;
  267. _combo.Visible = false;
  268. foreach (var vi in _radio) vi.Visible = false;
  269. if (_mode != modeinput) _input.Text = _text;
  270. _mode = modeinput;
  271. ControlAdjust();
  272. }
  273. /// <summary>切换到下拉选择模式。</summary>
  274. public void GoCombo()
  275. {
  276. if (_mode == modeinput) _text = _input.Text;
  277. _mode = modecombo;
  278. _input.Visible = false;
  279. _combo.Visible = true;
  280. foreach (var vi in _radio) vi.Visible = false;
  281. ControlAdjust();
  282. }
  283. /// <summary>可选项中包含指定值。</summary>
  284. public bool Contain(string value)
  285. {
  286. foreach (var vi in _value)
  287. {
  288. if (vi == value) return true;
  289. }
  290. return false;
  291. }
  292. /// <summary>获取或设置下拉菜单的显示数量,最少显示 1 项。</summary>
  293. public int DropDownItems
  294. {
  295. get { return _combo.MaxDropDownItems; }
  296. set { _combo.MaxDropDownItems = (value > 0) ? value : 1; }
  297. }
  298. #endregion
  299. #region event
  300. /// <summary></summary>
  301. private void EventInit()
  302. {
  303. this.Resize += Event_Main_Resize;
  304. this.MouseMove += Event_Caption_MouseMove;
  305. this.MouseLeave += Event_Caption_MouseLeave;
  306. this.MouseDown += Event_Caption_MouseDown;
  307. _left.MouseMove += Event_Caption_MouseMove;
  308. _left.MouseLeave += Event_Caption_MouseLeave;
  309. _left.MouseDown += Event_Caption_MouseDown;
  310. _right.MouseMove += Event_Caption_MouseMove;
  311. _right.MouseLeave += Event_Caption_MouseLeave;
  312. _right.MouseDown += Event_Caption_MouseDown;
  313. _label.MouseMove += Event_Caption_MouseMove;
  314. _label.MouseLeave += Event_Caption_MouseLeave;
  315. _label.MouseDown += Event_Caption_MouseDown;
  316. _input.MouseMove += Event_Caption_MouseMove;
  317. _input.MouseLeave += Event_Caption_MouseLeave;
  318. _input.GotFocus += Event_GotFocus;
  319. _input.LostFocus += Event_LostFocus;
  320. _input.TextChanged += Event_Input_TextChanged;
  321. _input.KeyDown += (s, e) => OnKeyDown(e);
  322. _input.KeyUp += (s, e) => OnKeyUp(e);
  323. _input.KeyPress += (s, e) => OnKeyPress(e);
  324. _combo.DrawItem += Event_Combo_DrawItem;
  325. _combo.SelectedIndexChanged += Event_Combo_SelectedIndexChanged;
  326. _combo.MouseMove += Event_Caption_MouseMove;
  327. _combo.MouseLeave += Event_Caption_MouseLeave;
  328. }
  329. /// <summary></summary>
  330. private void Event_Input_TextChanged(object sender, EventArgs e)
  331. {
  332. // 抛出事件
  333. if ((Changed != null) && (!Locked)) Changed(this, new EventArgs());
  334. }
  335. /// <summary></summary>
  336. private void Event_Radio_MouseDown(object sender, MouseEventArgs e)
  337. {
  338. if (Locked) return;
  339. Text = ((BlockButton)sender).Tag.ToString();
  340. //updatemode();
  341. }
  342. /// <summary></summary>
  343. private void Event_Combo_SelectedIndexChanged(object sender, EventArgs e)
  344. {
  345. if (Locked) return;
  346. if (_combo.SelectedIndex < 0) return;
  347. if (_combo.SelectedIndex >= _combo.Items.Count) return;
  348. var vold = string.IsNullOrEmpty(_text) ? "" : _text;
  349. var vnew = string.IsNullOrEmpty(_value[_combo.SelectedIndex]) ? "" : _value[_combo.SelectedIndex];
  350. var vchanged = (vold != vnew);
  351. _text = vnew;
  352. if (vchanged && (Changed != null)) Changed(this, new EventArgs());
  353. }
  354. /// <summary></summary>
  355. private void Event_Combo_DrawItem(object sender, DrawItemEventArgs e)
  356. {
  357. if (e.Index < 0) return;
  358. e.DrawBackground();
  359. e.DrawFocusRectangle();
  360. var vs = _combo.Items[e.Index].ToString();
  361. var vx = e.Bounds.X + 7;
  362. var vy = e.Bounds.Y + (_combo.ItemHeight - 16) / 2;
  363. var vb = new SolidBrush(e.ForeColor);
  364. if (_color != null)
  365. {
  366. if (e.Index < _color.Count)
  367. {
  368. vb.Dispose();
  369. vb = new SolidBrush(_color[e.Index]);
  370. }
  371. }
  372. e.Graphics.DrawString(vs, FormsUtility.DefaultFont, vb, vx, vy);
  373. vb.Dispose();
  374. }
  375. /// <summary></summary>
  376. private void Event_LostFocus(object sender, EventArgs e)
  377. {
  378. _statefocus = false; GoColor();
  379. }
  380. /// <summary></summary>
  381. private void Event_GotFocus(object sender, EventArgs e)
  382. {
  383. _statefocus = true; GoColor();
  384. }
  385. /// <summary></summary>
  386. private void Event_Caption_MouseDown(object sender, MouseEventArgs e)
  387. {
  388. _input.Focus();
  389. }
  390. /// <summary></summary>
  391. private void Event_Main_Resize(object sender, EventArgs e)
  392. {
  393. ControlAdjust();
  394. }
  395. /// <summary></summary>
  396. private void Event_Caption_MouseLeave(object sender, EventArgs e)
  397. {
  398. _statehover = false; GoColor();
  399. }
  400. /// <summary></summary>
  401. private void Event_Caption_MouseMove(object sender, MouseEventArgs e)
  402. {
  403. _statehover = true; GoColor();
  404. }
  405. #endregion
  406. #region property
  407. /// <summary>标签文本。</summary>
  408. public string Caption
  409. {
  410. get { return _label.Text; }
  411. set { _label.Text = string.IsNullOrEmpty(value) ? "" : value; }
  412. }
  413. /// <summary>内容文本。</summary>
  414. public new string Text
  415. {
  416. get
  417. {
  418. switch (_mode)
  419. {
  420. case modeinput: return _input.Text;
  421. default: return _text;
  422. }
  423. }
  424. set
  425. {
  426. switch (_mode)
  427. {
  428. case modeinput:
  429. _input.Text = string.IsNullOrEmpty(value) ? "" : value;
  430. break;
  431. default:
  432. var vchanged = (_text != value);
  433. _text = string.IsNullOrEmpty(value) ? "" : value;
  434. if (vchanged && (Changed != null)) Changed(this, new EventArgs());
  435. break;
  436. }
  437. // 更新下拉菜单。
  438. if (_mode == modecombo)
  439. {
  440. //var vexist = false;
  441. for (int i = 0; i < _value.Count; i++)
  442. {
  443. if (_value[i] == Text)
  444. {
  445. //vexist = true;
  446. _combo.SelectedIndex = i;
  447. }
  448. }
  449. //if (!vexist)
  450. //{
  451. // add(_input.Text, _input.Text);
  452. // _combo.SelectedIndex = _combo.Items.Count - 1;
  453. //}
  454. }
  455. // 更新单选按钮。
  456. if (_mode == moderadio)
  457. {
  458. for (int i = 0; i < _radio.Count; i++)
  459. {
  460. if (_value[i] == Text) GoCurrent(_radio[i]);
  461. else GoCandidate(_radio[i]);
  462. }
  463. }
  464. }
  465. }
  466. /// <summary>内容文本最大长度。</summary>
  467. public int Capacity
  468. {
  469. get { return _input.MaxLength; }
  470. set { _input.MaxLength = (value < 0) ? 0 : value; }
  471. }
  472. /// <summary></summary>
  473. public float FontSize
  474. {
  475. get { return _input.Font.Size; }
  476. set { _input.Font = new Font(FormsUtility.DefaultFontName, value); }
  477. }
  478. /// <summary>以默认的密码字符显示。</summary>
  479. public bool Password
  480. {
  481. get { return _input.UseSystemPasswordChar; }
  482. set { _input.UseSystemPasswordChar = value; }
  483. }
  484. /// <summary>独立控件,不接受 Tab 键事件。</summary>
  485. public bool Lonely
  486. {
  487. get { return !_input.TabStop; } // return _lonely; }
  488. set { _input.TabStop = !value; } // _lonely = value; _input.AcceptsTab = !value; }
  489. }
  490. /// <summary>锁定内容,禁止编辑。</summary>
  491. public override bool Locked
  492. {
  493. get { return _input.ReadOnly; }
  494. set
  495. {
  496. switch (_mode)
  497. {
  498. case modeinput:
  499. _input.ReadOnly = value;
  500. break;
  501. case moderadio:
  502. foreach (var vi in _radio) vi.Locked = value;
  503. break;
  504. case modecombo:
  505. _combo.Visible = !value;
  506. break;
  507. }
  508. GoColor();
  509. }
  510. }
  511. /// <summary>内容为空。</summary>
  512. public bool IsEmpty
  513. {
  514. get { return string.IsNullOrEmpty(_input.Text); }
  515. }
  516. #endregion
  517. #region color
  518. private Color _normalborder = FormsUtility.GraceBorder;
  519. private Color _normalleft = FormsUtility.White;
  520. private Color _normalright = FormsUtility.White;
  521. private Color _normalcaption = FormsUtility.GraceLocked;
  522. private Color _normaltext = FormsUtility.Black;
  523. private Color _hoverborder = FormsUtility.GraceSilver;
  524. private Color _hoverleft = FormsUtility.White;
  525. private Color _hoverright = FormsUtility.White;
  526. private Color _hovercaption = FormsUtility.GraceLocked;
  527. private Color _hovertext = FormsUtility.Black;
  528. private Color _focusborder = FormsUtility.GraceSilver; //FormsUtility.silver;
  529. private Color _focusleft = FormsUtility.White; //FormsUtility.wall;
  530. private Color _focusright = FormsUtility.White;
  531. private Color _focuscaption = FormsUtility.GraceMinor;// FormsUtility.gray;
  532. private Color _focustext = FormsUtility.Black;
  533. /// <summary></summary>
  534. public Color NormalBorder { get { return _normalborder; } set { if (value != null) _normalborder = value; GoColor(); } }
  535. /// <summary></summary>
  536. public Color NormalLeft { get { return _normalleft; } set { if (value != null) _normalleft = value; GoColor(); } }
  537. /// <summary></summary>
  538. public Color NormalRight { get { return _normalright; } set { if (value != null) _normalright = value; GoColor(); } }
  539. /// <summary></summary>
  540. public Color NormalCaption { get { return _normalcaption; } set { if (value != null) _normalcaption = value; GoColor(); } }
  541. /// <summary></summary>
  542. public Color NormalText { get { return _normaltext; } set { if (value != null) _normaltext = value; GoColor(); } }
  543. /// <summary></summary>
  544. public Color HoverBorder { get { return _hoverborder; } set { if (value != null) _hoverborder = value; GoColor(); } }
  545. /// <summary></summary>
  546. public Color HoverLeft { get { return _hoverleft; } set { if (value != null) _hoverleft = value; GoColor(); } }
  547. /// <summary></summary>
  548. public Color HoverRight { get { return _hoverright; } set { if (value != null) _hoverright = value; GoColor(); } }
  549. /// <summary></summary>
  550. public Color HoverCaption { get { return _hovercaption; } set { if (value != null) _hovercaption = value; GoColor(); } }
  551. /// <summary></summary>
  552. public Color HoverText { get { return _hovertext; } set { if (value != null) _hovertext = value; GoColor(); } }
  553. /// <summary></summary>
  554. public Color FocusBorder { get { return _focusborder; } set { if (value != null) _focusborder = value; GoColor(); } }
  555. /// <summary></summary>
  556. public Color FocusLeft { get { return _focusleft; } set { if (value != null) _focusleft = value; GoColor(); } }
  557. /// <summary></summary>
  558. public Color FocusRight { get { return _focusright; } set { if (value != null) _focusright = value; GoColor(); } }
  559. /// <summary></summary>
  560. public Color FocusCaption { get { return _focuscaption; } set { if (value != null) _focuscaption = value; GoColor(); } }
  561. /// <summary></summary>
  562. public Color FocusText { get { return _focustext; } set { if (value != null) _focustext = value; GoColor(); } }
  563. #endregion
  564. //protected override void OnEnabledChanged(EventArgs e)
  565. //{
  566. // if (Enabled == false)
  567. // {
  568. // SetStyle(ControlStyles.UserPaint, true);
  569. // }
  570. // else
  571. // {
  572. // SetStyle(ControlStyles.UserPaint, false);
  573. // }
  574. // base.OnEnabledChanged(e);
  575. //}
  576. //protected override void OnPaint(PaintEventArgs pe)
  577. //{
  578. // base.OnPaint(pe);
  579. // if (Enabled == false)
  580. // {
  581. // pe.Graphics.FillRectangle(new SolidBrush(SystemColors.ControlLight),
  582. // pe.ClipRectangle);
  583. // int x = 0, y = 0;
  584. // Size s = pe.Graphics.MeasureString(Text, Font).ToSize();
  585. // x = Width - s.Width;
  586. // y = (Height - s.Height) / 2;
  587. // pe.Graphics.DrawString(this.Text, this.Font, Brushes.Black, x, y);
  588. // }
  589. //}
  590. }
  591. }
  592. #endif