Visual Studio 如何删除文本框的顶部和两侧边框

klh5stk1  于 2023-10-23  发布在  其他
关注(0)|答案(2)|浏览(315)

我与斗争如何删除顶部和文本框的Windows窗体项目的双方边界
我希望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;

你能帮我一下吗?

lfapxunr

lfapxunr1#

首先,快速肮脏的解决方案

创建一个带有重复下划线字符的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+。登录表单的屏幕截图是:

不像微软的页面那么优雅,但它可以完成工作。

展开查看全部
xytpbqjk

xytpbqjk2#

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

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

你当然可以添加其他的东西,你去(例如,添加一些图形元素,这是很简单的)

构建此UserControl

  • 向项目中添加一个新的UserControl,命名为TextBoxInput(目前)
  • 将其Width设置为150
  • 将其Padding设置为(3, 10, 3, 1)BorderStyle = None
  • 设置其AutoScaleMode = Dpi
  • 添加一个文本框,将其命名为EditControl并将其停靠到Top
  • 更改UserControl的BackColorForeColor属性以匹配TextBox的属性
  • 将代码文件中的内容替换为此处的代码(保留namespace
  • 生成项目,在工具箱中找到UserControl并将其放到窗体上
  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. }

自定义设计器。这只是用来删除一些不相关的属性和分配给控件的默认文本(因此显示提示横幅)。

要在.NET 5+应用程序中使用设计器,请通过NuGetPackage Manager安装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. }

它是这样工作的

展开查看全部

相关问题