namespace System.Windows.Forms { public class TextBox : Control { private System.Windows.Controls.TextBox textBox; private System.Windows.Controls.PasswordBox passwordBox; protected new System.Windows.Controls.ContentControl control { get; } private bool IsPassword => control.Content == passwordBox; private System.Windows.Controls.Control InnerControl => control.Content as System.Windows.Controls.Control; internal bool IsFocused => InnerControl.IsFocused; internal bool IsMouseOver => InnerControl.IsMouseOver; public override string Text { get { if (IsPassword) return passwordBox.Password; else { if (Multiline) return textBox.Text; return textBox.Text.Replace(((char)1).ToString(), "\r\n"); } } set { if (IsPassword) passwordBox.Password = value; else { if (Multiline) textBox.Text = value; else textBox.Text = string.IsNullOrEmpty(value) ? value : value.Replace("\r\n", ((char)1).ToString()); } } } public int MaxLength { get => textBox.MaxLength; set => textBox.MaxLength = value; } private bool multiline; public bool Multiline { get => multiline; set { multiline = value; WordWrap = value ? WordWrap : false; textBox.AcceptsReturn = value || AcceptsReturn; } } public bool AcceptsReturn { get => textBox.AcceptsReturn; set => textBox.AcceptsReturn = value; } public bool AcceptsTab { get => textBox.AcceptsTab; set => textBox.AcceptsTab = value; } public bool ReadOnly { get => textBox.IsReadOnly; set => textBox.IsReadOnly = value; } public bool Modified { get; set; } public int SelectionStart { get => textBox.SelectionStart; set => textBox.SelectionStart = value; } public int SelectionLength { get => textBox.SelectionLength; set => textBox.SelectionLength = value; } public string SelectedText { get => textBox.SelectedText; set => textBox.SelectedText = value; } private bool wordWrap; public bool WordWrap { get => wordWrap; set { wordWrap = value; if (Multiline) textBox.TextWrapping = value ? TextWrapping.Wrap : TextWrapping.NoWrap; } } private ScrollBars scrollBars; public ScrollBars ScrollBars { get => scrollBars; set { scrollBars = value; if (value == ScrollBars.None) { textBox.HorizontalScrollBarVisibility = Windows.Controls.ScrollBarVisibility.Hidden; textBox.VerticalScrollBarVisibility = Windows.Controls.ScrollBarVisibility.Hidden; } else if (value == ScrollBars.Horizontal) { textBox.HorizontalScrollBarVisibility = Windows.Controls.ScrollBarVisibility.Visible; textBox.VerticalScrollBarVisibility = Windows.Controls.ScrollBarVisibility.Hidden; } else if (value == ScrollBars.Vertical) { textBox.HorizontalScrollBarVisibility = Windows.Controls.ScrollBarVisibility.Hidden; textBox.VerticalScrollBarVisibility = Windows.Controls.ScrollBarVisibility.Visible; } else if (value == ScrollBars.Both) { textBox.HorizontalScrollBarVisibility = Windows.Controls.ScrollBarVisibility.Visible; textBox.VerticalScrollBarVisibility = Windows.Controls.ScrollBarVisibility.Visible; } } } private char passwordChar; public char PasswordChar { get => passwordChar; set { passwordChar = value; control.Content = value != 0 ? passwordBox : textBox; } } public bool UseSystemPasswordChar { get => PasswordChar == '*'; set => PasswordChar = value ? '*' : '\0'; } private HorizontalAlignment textAlign; public HorizontalAlignment TextAlign { get => textAlign; set { textAlign = value; textBox.HorizontalContentAlignment = value switch { HorizontalAlignment.Center => Windows.HorizontalAlignment.Center, HorizontalAlignment.Right => Windows.HorizontalAlignment.Right, _ => Windows.HorizontalAlignment.Left }; } } public override BorderStyle BorderStyle { get => textBox.BorderThickness.Left == 0 ? BorderStyle.None : BorderStyle.FixedSingle; set { textBox.BorderThickness = passwordBox.BorderThickness = new Thickness(value == BorderStyle.None ? 0 : 1); if (value == BorderStyle.None) { textBox.Padding = passwordBox.Padding = new Thickness(0); } } } public bool HideSelection { get => !textBox.IsInactiveSelectionHighlightEnabled; set => textBox.IsInactiveSelectionHighlightEnabled = !value; } private CharacterCasing characterCasing; public CharacterCasing CharacterCasing { get => characterCasing; set { characterCasing = value; textBox.CharacterCasing = value switch { CharacterCasing.Upper => Windows.Controls.CharacterCasing.Upper, CharacterCasing.Lower => Windows.Controls.CharacterCasing.Lower, _ => Windows.Controls.CharacterCasing.Normal }; } } public bool CanUndo => textBox.CanUndo; public string[] Lines { get => Text.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); set => Text = String.Join(Environment.NewLine, value); } public override Padding Padding { get => Helper.ThicknessToPadding(textBox.Padding); set => textBox.Padding = passwordBox.Padding = Helper.PaddingToThickness(value); } public override Drawing.Size PreferredSize => new Drawing.Size(Width, (int)((BorderStyle == BorderStyle.None ? 16 : 20) * DpiScale)); protected override void SetControlHeight(int value) { if (multiline) base.SetControlHeight(value); } public int GetCharIndexFromPosition(System.Drawing.Point pos) => textBox.GetCharacterIndexFromPoint(new System.Windows.Point(pos.X / DpiScale, pos.Y / DpiScale), true); public void Select(int start, int length) => textBox.Select(start, length); public void SelectAll() => textBox.SelectAll(); public void Copy() => textBox.Copy(); public void Cut() => textBox.Cut(); public void Paste() => textBox.Paste(); public void Undo() => textBox.Undo(); public new void Focus() { if (control.IsLoaded) InnerControl.Focus(); else control.Dispatcher.InvokeAsync(() => InnerControl.Focus(), Threading.DispatcherPriority.Loaded); } public TextBox() { textBox = new() { Tag = this }; passwordBox = new() { Tag = this }; textBox.Padding = passwordBox.Padding = new Thickness(0, 1, 0, 2); control = new(); SetControl(control); control.Content = textBox; Width = 100; Height = 22; WordWrap = true; textBox.TextChanged += (sender, e) => { Modified = true; OnTextChanged(e); }; // WPF TextBox has issues with regular DragOver & Drop events control.PreviewDragOver += (sender, e) => { OnDragOver(Helper.GetDragEventArgs(control, e)); e.Handled = true; }; control.PreviewDrop += (sender, e) => { OnDragDrop(Helper.GetDragEventArgs(control, e)); e.Handled = true; }; // this control needs its own logic of DoubleClick (see Control.cs for explanation) control.MouseDoubleClick += (sender, e) => OnDoubleClick(e); // SWF consistency: some text boxes handle Enter&Esc in their KeyPress handler control.PreviewKeyDown += (sender, e) => { if (e.Key == Input.Key.Enter || e.Key == Input.Key.Escape) { var args = new KeyPressEventArgs(e.Key == Input.Key.Enter ? (char)13 : (char)27); OnKeyPress(args); e.Handled = args.Handled; } }; } } }