如何移除文本框的顶部和两侧边框

huangapple go评论179阅读模式
英文:

How to remove border of top and both sides of a TextBox

问题

我遇到了如何移除 Windows Forms 项目中 TextBox 顶部和两侧边框的问题。

我希望 TextBox 看起来像这样:

如何移除文本框的顶部和两侧边框

我的文本框代码:

  1. this.textBox1.Anchor = System.Windows.Forms.AnchorStyles.None;
  2. this.textBox1.Location = new System.Drawing.Point(85, 101);
  3. this.textBox1.Name = "textBox1";
  4. this.textBox1.PlaceholderText = "Login";
  5. this.textBox1.Size = new System.Drawing.Size(213, 23);
  6. this.textBox1.TabIndex = 0;
  7. this.textBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;

你能帮我解决这个问题吗?

英文:

I'm with struggle with how to remove border of top and both sides of TextBox in Windows Forms project

I want the TextBox looks like this:

如何移除文本框的顶部和两侧边框

My textbox code:

  1. this.textBox1.Anchor = System.Windows.Forms.AnchorStyles.None;
  2. this.textBox1.Location = new System.Drawing.Point(85, 101);
  3. this.textBox1.Name = "textBox1";
  4. this.textBox1.PlaceholderText = "Login";
  5. this.textBox1.Size = new System.Drawing.Size(213, 23);
  6. this.textBox1.TabIndex = 0;
  7. this.textBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;

Could you help me with this?

答案1

得分: 3

首先,快速且简单的解决方案

创建一个Label,其中包含重复的下划线字符,并将其定位在登录TextBox的底部:

  1. txtName.BorderStyle = BorderStyle.None;
  2. Label lblBottomBorder = new Label();
  3. lblBottomBorder.ForeColor = Color.Blue;
  4. lblBottomBorder.Width = txtName.Width + 8;
  5. lblBottomBorder.Text = new String('_', 250);
  6. lblBottomBorder.Location = new Point(txtName.Location.X - 3, txtName.Location.Y + 3);
  7. Controls.Add(lblBottomBorder);

编辑:

第二种更灵活的解决方案

覆盖Form.OnPaint()方法,并使用Graphics.DrawLine()方法在登录TextBox下面绘制自定义线条:

  1. public partial class FrmLogin : Form
  2. {
  3. public FrmLogin()
  4. {
  5. InitializeComponent();
  6. Text = "Login";
  7. StartPosition = FormStartPosition.CenterScreen;
  8. MaximizeBox = false;
  9. MinimizeBox = false;
  10. FormBorderStyle = FormBorderStyle.FixedDialog;
  11. Font = new Font("Segoe UI", 10);
  12. BackColor = Color.White;
  13. AcceptButton = btnOK;
  14. Activated += (sender, e) => txtEmail.PlaceholderText = "Email, phone or Skype";
  15. lblEnter.Font = new Font("Segoe UI", 14, FontStyle.Bold);
  16. txtEmail.BorderStyle = BorderStyle.None;
  17. txtEmail.ForeColor = Color.DimGray;
  18. btnOK.BackColor = Color.DarkBlue;
  19. btnOK.ForeColor = Color.White;
  20. }
  21. protected override void OnPaint(PaintEventArgs e)
  22. {
  23. Point txtEmailLocation = PointToClient(PointToScreen(txtEmail.Location));
  24. var lineStart = new Point(txtEmailLocation.X, txtEmailLocation.Y + txtEmail.Height + 7);
  25. var lineEnd = new Point(txtEmailLocation.X + txtEmail.Width, txtEmailLocation.Y + txtEmail.Height + 7);
  26. Pen pen = new Pen(Color.Blue) { Width = 2 };
  27. e.Graphics.DrawLine(pen, lineStart, lineEnd);
  28. }
  29. }

请注意,TextBox.PlaceholderText属性需要.NET 5+。登录表单的屏幕截图如下:

如何移除文本框的顶部和两侧边框

虽然不像Microsoft页面那样优雅,但能完成任务。

英文:

First, quick and dirty solution

Create a Label with repeated underscore characters and locate it at the bottom of the login TextBox:

  1. txtName.BorderStyle = BorderStyle.None;
  2. Label lblBottomBorder = new Label();
  3. lblBottomBorder.ForeColor = Color.Blue;
  4. lblBottomBorder.Width = txtName.Width + 8;
  5. lblBottomBorder.Text = new String('_', 250);
  6. lblBottomBorder.Location = new Point(txtName.Location.X - 3, txtName.Location.Y + 3);
  7. Controls.Add(lblBottomBorder);

EDIT:

Second and more flexible solution

Override the Form.OnPaint() method and draw a custom line under the login TextBox using the Graphics.DrawLine() method:

  1. public partial class FrmLogin : Form
  2. {
  3. public FrmLogin()
  4. {
  5. InitializeComponent();
  6. Text = "Login";
  7. StartPosition = FormStartPosition.CenterScreen;
  8. MaximizeBox = false;
  9. MinimizeBox = false;
  10. FormBorderStyle = FormBorderStyle.FixedDialog;
  11. Font = new Font("Segoe UI", 10);
  12. BackColor = Color.White;
  13. AcceptButton = btnOK;
  14. Activated += (sender, e) => txtEmail.PlaceholderText = "Email, phone or Skype";
  15. lblEnter.Font = new Font("Segoe UI", 14, FontStyle.Bold);
  16. txtEmail.BorderStyle = BorderStyle.None;
  17. txtEmail.ForeColor = Color.DimGray;
  18. btnOK.BackColor = Color.DarkBlue;
  19. btnOK.ForeColor = Color.White;
  20. }
  21. protected override void OnPaint(PaintEventArgs e)
  22. {
  23. Point txtEmailLocation = PointToClient(PointToScreen(txtEmail.Location));
  24. var lineStart = new Point(txtEmailLocation.X, txtEmailLocation.Y + txtEmail.Height + 7);
  25. var lineEnd = new Point(txtEmailLocation.X + txtEmail.Width, txtEmailLocation.Y + txtEmail.Height + 7);
  26. Pen pen = new Pen(Color.Blue) { Width = 2 };
  27. e.Graphics.DrawLine(pen, lineStart, lineEnd);
  28. }
  29. }

Please note that the TextBox.PlaceholderText property requires .NET 5+. The screenshot of the login form is:

如何移除文本框的顶部和两侧边框

Not as elegant as the Microsoft page but it gets the job done.

答案2

得分: 2

尝试使用这个简单的UserControl。它只包含一个标准的TextBox控件,并添加了一些属性来定义新的行为。

  • 它提供了自定义绘制背景以显示底部可调整大小的线条
  • 允许更改底线的颜色
  • 根据当前TextBox的大小自动调整大小(例如,当您更改字体时)
  • 可以设置Cue Banner(灰色文本),当文本为空时
  • 允许设置输入框用于输入密码时的替换字符
  • 允许右到左布局

当然,您可以随时添加其他内容(例如,添加一些图形元素相当简单)

要构建此UserControl:

  • 向项目添加一个新的UserControl,命名为 TextBoxInput(暂时命名为此)
  • 将其Width设置为 150
  • 将其Padding设置为 (3, 10, 3, 1),并将BorderStyle设置为 None
  • 将其AutoScaleMode设置为 Dpi
  • 添加一个TextBox,命名为 EditControl,并将其停靠到Top
  • 更改UserControl的BackColorForeColor属性以匹配TextBox的属性
  • 使用此处找到的代码替换代码文件中的内容(保留namespace
  • 构建项目,在工具箱中找到您的UserControl,并将其拖放到窗体上

自定义设计器。仅用于删除一些无关的属性和对控件分配的默认文本(以便显示Cue Banner)。

要在.NET 5+应用程序中使用设计器,请通过NuGet包管理器安装Microsoft.WinForms.Designer.SDK支持。

  1. public class TextBoxInputDesigner : ControlDesigner {
  2. private readonly string[] RemovedProperties = new[] {
  3. "AutoSize", "AutoSizeMode", "AutoScroll", "AutoScrollMargin", "AutoScrollMinSize",
  4. "BackgroundImage", "BackgroundImageLayout", "Cursor"
  5. };
  6. public TextBoxInputDesigner() { }
  7. public override void InitializeNewComponent(IDictionary defaultValues) {
  8. base.InitializeNewComponent(defaultValues);
  9. var descriptor = TypeDescriptor.GetProperties(Component)["Text"];
  10. if (descriptor != null && (descriptor.PropertyType == typeof(string))) {
  11. descriptor.SetValue(Component, string.Empty);
  12. }
  13. }
  14. protected override void PreFilterProperties(IDictionary properties) {
  15. foreach (string prop in RemovedProperties) {
  16. properties.Remove(prop);
  17. }
  18. base.PreFilterProperties(properties);
  19. }
  20. }

这是它的工作原理:

如何移除文本框的顶部和两侧边框

英文:

Try out this simple UserControl. It just contains a standard TextBox Control and adds some properties to define the new behavior.

  • It provides custom painting of the background to show a resizable line at the bottom
  • Allows to change the Color of the bottom line
  • Auto-sizes depending on the current TextBox size (e.g, when you change the Font)
  • Can set a Cue Banner (grayed text) when the text is empty
  • Allows to set a replacement char when the input box is used to enter a Password
  • Allows Right-To-Left layout

You can of course add other stuff as you go (e.g., adding some graphic elements it's quite simple)


To build this UserControl:

  • Add a new UserControl to the Project, name it TextBoxInput (for now)
  • Set its Width to 150
  • Set its Padding to (3, 10, 3, 1) and BorderStyle = None
  • Set its AutoScaleMode = Dpi
  • Add a TextBox, name it EditControl and dock it to Top
  • Change the BackColor and ForeColor properties of the UserControl to match the TextBox's properties
  • Replace what's in the code file with the code you find here (preserving the namespace)
  • Build the Project, find your UserControl in the ToolBox and drop it on a Form

  1. using System;
  2. using System.Collections;
  3. using System.ComponentModel;
  4. using System.Drawing;
  5. using System.Runtime.InteropServices;
  6. using System.Windows.Forms;
  7. using System.Windows.Forms.Design;
  8. [Designer(typeof(TextBoxInputDesigner))]
  9. public partial class TextBoxInput : UserControl {
  10. private string m_CueBanner = string.Empty;
  11. private bool m_CueBannerShowOnFocus = true;
  12. private Color m_LineColor = Color.CadetBlue;
  13. private int m_LineDistance = 4;
  14. private int m_LineHeight = 1;
  15. public TextBoxInput() {
  16. InitializeComponent();
  17. ResizeRedraw = true;
  18. Padding = new Padding(3, 10, 3, 1);
  19. EditControl.TextChanged += (_, __) => OnTextChangedInternal(EditControl.Text, false);
  20. EditControl.HandleCreated += (_, __) => SetCueBanner(EditControl.Handle, m_CueBanner, m_CueBannerShowOnFocus);
  21. CueBanner = "<Enter CueBanner>";
  22. }
  23. public string CueBanner {
  24. get => m_CueBanner;
  25. set {
  26. m_CueBanner = value;
  27. SetCueBanner(EditControl.Handle, m_CueBanner, m_CueBannerShowOnFocus);
  28. }
  29. }
  30. [DefaultValue(true)]
  31. public bool CueBannerShowOnFocus {
  32. get => m_CueBannerShowOnFocus;
  33. set {
  34. m_CueBannerShowOnFocus = value;
  35. SetCueBanner(EditControl.Handle, m_CueBanner, m_CueBannerShowOnFocus);
  36. }
  37. }
  38. public Color LineColor {
  39. get => m_LineColor;
  40. set {
  41. m_LineColor = value;
  42. Invalidate();
  43. }
  44. }
  45. [DefaultValue(1), Description("Sets the height of the Line. Allowed values (1, 8)")]
  46. public int LineHeight {
  47. get => m_LineHeight;
  48. set {
  49. m_LineHeight = Math.Max(1, Math.Min(value, 8));
  50. Invalidate();
  51. OnResize(EventArgs.Empty);
  52. }
  53. }
  54. [DefaultValue(false)]
  55. public bool IsPassword {
  56. get => EditControl.UseSystemPasswordChar;
  57. set => EditControl.UseSystemPasswordChar = value;
  58. }
  59. [Bindable(true), Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
  60. [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
  61. public override string Text {
  62. get => base.Text;
  63. set {
  64. OnTextChangedInternal(value, true);
  65. }
  66. }
  67. protected override void OnBackColorChanged(EventArgs e) {
  68. base.OnBackColorChanged(e);
  69. EditControl.BackColor = base.BackColor;
  70. }
  71. protected override void OnForeColorChanged(EventArgs e) {
  72. base.OnForeColorChanged(e);
  73. EditControl.ForeColor = base.ForeColor;
  74. }
  75. protected override void OnLayout(LayoutEventArgs e) {
  76. base.OnLayout(e);
  77. ClientSize = new Size(ClientSize.Width, EditControl.Bounds.Bottom + m_LineDistance + m_LineHeight + 1);
  78. }
  79. protected override void OnPaintBackground (PaintEventArgs e) {
  80. base.OnPaintBackground(e);
  81. int yPos = EditControl.Bounds.Bottom + m_LineDistance + (m_LineHeight / 2);
  82. using (var pen = new Pen(m_LineColor, m_LineHeight)) {
  83. e.Graphics.DrawLine(pen, 0, yPos, ClientSize.Width, yPos);
  84. }
  85. }
  86. protected override void OnRightToLeftChanged(EventArgs e) {
  87. base.OnRightToLeftChanged(e);
  88. EditControl.RightToLeft = RightToLeft;
  89. }
  90. internal virtual void OnTextChangedInternal(string text, bool internalCall) {
  91. base.Text = text;
  92. if (internalCall) EditControl.Text = text;
  93. OnTextChanged(EventArgs.Empty);
  94. SetCueBanner(EditControl.Handle, m_CueBanner, m_CueBannerShowOnFocus);
  95. }
  96. public void SetCueBanner(IntPtr handle, string text, bool showOnFocus) {
  97. if (handle != IntPtr.Zero) {
  98. SendMessage(handle, EM_SETCUEBANNER, showOnFocus ? 1 : 0, text);
  99. }
  100. }
  101. private const int EM_SETCUEBANNER = 0x1501;
  102. [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
  103. private static extern int SendMessage(IntPtr hWnd, int msg, int wParam, string lParam);
  104. }

Custom designer. This is used just to remove some irrelevant properties and the default text assigned to a Control (so the Cue Banner is shown instead).

To use the designer in a .NET 5+ application, install, via NuGetPackage Manager, the Microsoft.WinForms.Designer.SDK support.

  1. public class TextBoxInputDesigner : ControlDesigner {
  2. private readonly string[] RemovedProperties = new[] {
  3. "AutoSize", "AutoSizeMode", "AutoScroll", "AutoScrollMargin","AutoScrollMinSize",
  4. "BackgroundImage", "BackgroundImageLayout", "Cursor"
  5. };
  6. public TextBoxInputDesigner() { }
  7. public override void InitializeNewComponent(IDictionary defaultValues) {
  8. base.InitializeNewComponent(defaultValues);
  9. var descriptor = TypeDescriptor.GetProperties(Component)["Text"];
  10. if (descriptor != null && (descriptor.PropertyType == typeof(string))) {
  11. descriptor.SetValue(Component, string.Empty);
  12. }
  13. }
  14. protected override void PreFilterProperties(IDictionary properties) {
  15. foreach (string prop in RemovedProperties) {
  16. properties.Remove(prop);
  17. }
  18. base.PreFilterProperties(properties);
  19. }
  20. }

This is how it works:

如何移除文本框的顶部和两侧边框

huangapple
  • 本文由 发表于 2023年8月10日 22:26:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76876685.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定