TextBox.cs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. namespace System.Windows.Forms
  2. {
  3. public class TextBox : Control
  4. {
  5. private System.Windows.Controls.TextBox textBox;
  6. private System.Windows.Controls.PasswordBox passwordBox;
  7. protected new System.Windows.Controls.ContentControl control { get; }
  8. private bool IsPassword => control.Content == passwordBox;
  9. private System.Windows.Controls.Control InnerControl => control.Content as System.Windows.Controls.Control;
  10. internal bool IsFocused => InnerControl.IsFocused;
  11. internal bool IsMouseOver => InnerControl.IsMouseOver;
  12. public override string Text
  13. {
  14. get
  15. {
  16. if (IsPassword)
  17. return passwordBox.Password;
  18. else
  19. {
  20. if (Multiline)
  21. return textBox.Text;
  22. return textBox.Text.Replace(((char)1).ToString(), "\r\n");
  23. }
  24. }
  25. set
  26. {
  27. if (IsPassword)
  28. passwordBox.Password = value;
  29. else
  30. {
  31. if (Multiline)
  32. textBox.Text = value;
  33. else
  34. textBox.Text = string.IsNullOrEmpty(value) ? value : value.Replace("\r\n", ((char)1).ToString());
  35. }
  36. }
  37. }
  38. public int MaxLength
  39. {
  40. get => textBox.MaxLength;
  41. set => textBox.MaxLength = value;
  42. }
  43. private bool multiline;
  44. public bool Multiline
  45. {
  46. get => multiline;
  47. set
  48. {
  49. multiline = value;
  50. WordWrap = value ? WordWrap : false;
  51. textBox.AcceptsReturn = value || AcceptsReturn;
  52. }
  53. }
  54. public bool AcceptsReturn
  55. {
  56. get => textBox.AcceptsReturn;
  57. set => textBox.AcceptsReturn = value;
  58. }
  59. public bool AcceptsTab
  60. {
  61. get => textBox.AcceptsTab;
  62. set => textBox.AcceptsTab = value;
  63. }
  64. public bool ReadOnly
  65. {
  66. get => textBox.IsReadOnly;
  67. set => textBox.IsReadOnly = value;
  68. }
  69. public bool Modified { get; set; }
  70. public int SelectionStart
  71. {
  72. get => textBox.SelectionStart;
  73. set => textBox.SelectionStart = value;
  74. }
  75. public int SelectionLength
  76. {
  77. get => textBox.SelectionLength;
  78. set => textBox.SelectionLength = value;
  79. }
  80. public string SelectedText
  81. {
  82. get => textBox.SelectedText;
  83. set => textBox.SelectedText = value;
  84. }
  85. private bool wordWrap;
  86. public bool WordWrap
  87. {
  88. get => wordWrap;
  89. set
  90. {
  91. wordWrap = value;
  92. if (Multiline)
  93. textBox.TextWrapping = value ? TextWrapping.Wrap : TextWrapping.NoWrap;
  94. }
  95. }
  96. private ScrollBars scrollBars;
  97. public ScrollBars ScrollBars
  98. {
  99. get => scrollBars;
  100. set
  101. {
  102. scrollBars = value;
  103. if (value == ScrollBars.None)
  104. {
  105. textBox.HorizontalScrollBarVisibility = Windows.Controls.ScrollBarVisibility.Hidden;
  106. textBox.VerticalScrollBarVisibility = Windows.Controls.ScrollBarVisibility.Hidden;
  107. }
  108. else if (value == ScrollBars.Horizontal)
  109. {
  110. textBox.HorizontalScrollBarVisibility = Windows.Controls.ScrollBarVisibility.Visible;
  111. textBox.VerticalScrollBarVisibility = Windows.Controls.ScrollBarVisibility.Hidden;
  112. }
  113. else if (value == ScrollBars.Vertical)
  114. {
  115. textBox.HorizontalScrollBarVisibility = Windows.Controls.ScrollBarVisibility.Hidden;
  116. textBox.VerticalScrollBarVisibility = Windows.Controls.ScrollBarVisibility.Visible;
  117. }
  118. else if (value == ScrollBars.Both)
  119. {
  120. textBox.HorizontalScrollBarVisibility = Windows.Controls.ScrollBarVisibility.Visible;
  121. textBox.VerticalScrollBarVisibility = Windows.Controls.ScrollBarVisibility.Visible;
  122. }
  123. }
  124. }
  125. private char passwordChar;
  126. public char PasswordChar
  127. {
  128. get => passwordChar;
  129. set
  130. {
  131. passwordChar = value;
  132. control.Content = value != 0 ? passwordBox : textBox;
  133. }
  134. }
  135. public bool UseSystemPasswordChar
  136. {
  137. get => PasswordChar == '*';
  138. set => PasswordChar = value ? '*' : '\0';
  139. }
  140. private HorizontalAlignment textAlign;
  141. public HorizontalAlignment TextAlign
  142. {
  143. get => textAlign;
  144. set
  145. {
  146. textAlign = value;
  147. textBox.HorizontalContentAlignment = value switch
  148. {
  149. HorizontalAlignment.Center => Windows.HorizontalAlignment.Center,
  150. HorizontalAlignment.Right => Windows.HorizontalAlignment.Right,
  151. _ => Windows.HorizontalAlignment.Left
  152. };
  153. }
  154. }
  155. public override BorderStyle BorderStyle
  156. {
  157. get => textBox.BorderThickness.Left == 0 ? BorderStyle.None : BorderStyle.FixedSingle;
  158. set
  159. {
  160. textBox.BorderThickness = passwordBox.BorderThickness = new Thickness(value == BorderStyle.None ? 0 : 1);
  161. if (value == BorderStyle.None)
  162. {
  163. textBox.Padding = passwordBox.Padding = new Thickness(0);
  164. }
  165. }
  166. }
  167. public bool HideSelection
  168. {
  169. get => !textBox.IsInactiveSelectionHighlightEnabled;
  170. set => textBox.IsInactiveSelectionHighlightEnabled = !value;
  171. }
  172. private CharacterCasing characterCasing;
  173. public CharacterCasing CharacterCasing
  174. {
  175. get => characterCasing;
  176. set
  177. {
  178. characterCasing = value;
  179. textBox.CharacterCasing = value switch
  180. {
  181. CharacterCasing.Upper => Windows.Controls.CharacterCasing.Upper,
  182. CharacterCasing.Lower => Windows.Controls.CharacterCasing.Lower,
  183. _ => Windows.Controls.CharacterCasing.Normal
  184. };
  185. }
  186. }
  187. public bool CanUndo => textBox.CanUndo;
  188. public string[] Lines
  189. {
  190. get => Text.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
  191. set => Text = String.Join(Environment.NewLine, value);
  192. }
  193. public override Padding Padding
  194. {
  195. get => Helper.ThicknessToPadding(textBox.Padding);
  196. set => textBox.Padding = passwordBox.Padding = Helper.PaddingToThickness(value);
  197. }
  198. public override Drawing.Size PreferredSize => new Drawing.Size(Width, (int)((BorderStyle == BorderStyle.None ? 16 : 20) * DpiScale));
  199. protected override void SetControlHeight(int value)
  200. {
  201. if (multiline)
  202. base.SetControlHeight(value);
  203. }
  204. public int GetCharIndexFromPosition(System.Drawing.Point pos) =>
  205. textBox.GetCharacterIndexFromPoint(new System.Windows.Point(pos.X / DpiScale, pos.Y / DpiScale), true);
  206. public void Select(int start, int length) => textBox.Select(start, length);
  207. public void SelectAll() => textBox.SelectAll();
  208. public void Copy() => textBox.Copy();
  209. public void Cut() => textBox.Cut();
  210. public void Paste() => textBox.Paste();
  211. public void Undo() => textBox.Undo();
  212. public new void Focus()
  213. {
  214. if (control.IsLoaded)
  215. InnerControl.Focus();
  216. else
  217. control.Dispatcher.InvokeAsync(() => InnerControl.Focus(), Threading.DispatcherPriority.Loaded);
  218. }
  219. public TextBox()
  220. {
  221. textBox = new() { Tag = this };
  222. passwordBox = new() { Tag = this };
  223. textBox.Padding = passwordBox.Padding = new Thickness(0, 1, 0, 2);
  224. control = new();
  225. SetControl(control);
  226. control.Content = textBox;
  227. Width = 100;
  228. Height = 22;
  229. WordWrap = true;
  230. textBox.TextChanged += (sender, e) =>
  231. {
  232. Modified = true;
  233. OnTextChanged(e);
  234. };
  235. // WPF TextBox has issues with regular DragOver & Drop events
  236. control.PreviewDragOver += (sender, e) =>
  237. {
  238. OnDragOver(Helper.GetDragEventArgs(control, e));
  239. e.Handled = true;
  240. };
  241. control.PreviewDrop += (sender, e) =>
  242. {
  243. OnDragDrop(Helper.GetDragEventArgs(control, e));
  244. e.Handled = true;
  245. };
  246. // this control needs its own logic of DoubleClick (see Control.cs for explanation)
  247. control.MouseDoubleClick += (sender, e) => OnDoubleClick(e);
  248. // SWF consistency: some text boxes handle Enter&Esc in their KeyPress handler
  249. control.PreviewKeyDown += (sender, e) =>
  250. {
  251. if (e.Key == Input.Key.Enter || e.Key == Input.Key.Escape)
  252. {
  253. var args = new KeyPressEventArgs(e.Key == Input.Key.Enter ? (char)13 : (char)27);
  254. OnKeyPress(args);
  255. e.Handled = args.Handled;
  256. }
  257. };
  258. }
  259. }
  260. }