文本框填充(padding)

34

我在互联网上搜索了很久,可能是用的关键词不对,因为我找不到任何有用的信息。我想创建一个文本框,使文本距离左侧有一定距离。

http://dab.biz/images/screenie/2011-02-04_1316.png

就像这样。

6个回答

51

很可能您已经发现了,Winforms文本框没有填充属性。由于面板公开了填充属性,因此一种技术是:

  1. 创建一个面板
  2. 将其边框设置为与文本框匹配(例如Fixed3D)
  3. 将其背景颜色设置为与文本框匹配(例如白色或窗口)
  4. 设置其填充以满足您的需求(例如10,3,10,3)
  5. 在面板内添加一个文本框
  6. 将文本框的边框设置为无
  7. 使用文本框的停靠和锚定属性来得到所需的效果

这应该可以让您开始工作。您还可以创建一个自定义控件,完成与上述相同的操作。

如果您谈论的是asp.net中的文本框,请使用CSS:
input[type="text"] {padding: 3px 10px}


4
问题在于许多新的Windows界面主题中,TextBox上的Fixed3D外观与Panel上的不同。 - KeithS
3
将您的面板设置为具有单击事件来聚焦文本框可能是个好主意。由于这个新的填充区域看起来像是文本框的一部分,如果用户点击它但无法将焦点聚焦在文本框上,可能会让用户感到困惑。 - Adam Plocher
@AdamPlocher 在asp.net的情况下 :) - Anirudha Gupta

14

好的,这里是一个适当的解决方案。首先将您的TextBox控件的Multiline属性设置为true

需要使用的命名空间:

using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

代码:

private const int EM_SETRECT = 0xB3;

[DllImport(@"User32.dll", EntryPoint = @"SendMessage", CharSet = CharSet.Auto)]
private static extern int SendMessageRefRect(IntPtr hWnd, uint msg, int wParam, ref RECT rect);

[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
    public readonly int Left;
    public readonly int Top;
    public readonly int Right;
    public readonly int Bottom;

    private RECT(int left, int top, int right, int bottom)
    {
        Left = left;
        Top = top;
        Right = right;
        Bottom = bottom;
    }

    public RECT(Rectangle r) : this(r.Left, r.Top, r.Right, r.Bottom)
    {
    }
}
public void SetPadding(TextBox textBox, Padding padding)
{
    var rect = new Rectangle(padding.Left, padding.Top, textBox.ClientSize.Width - padding.Left - padding.Right, textBox.ClientSize.Height - padding.Top - padding.Bottom);
    RECT rc = new RECT(rect );
    SendMessageRefRect(textBox.Handle, EM_SETRECT, 0, ref rc);
}
现在这样调用:
SetPadding(myTextBox, new Padding(5, 5, 5, 5));

当然,最好的方法是创建自己的TextBox控件,可以自动设置Multiline为true并阻止文本中不需要的换行等。


1
这个解决方案适用于 Windows 10 的 TextBox 样式吗?在我的 Windows 10 安装中,无论选择哪种 BorderStyle 都不会有任何可见的效果,就像这个答案中的代码一样。 - silviubogan

7

你可以使用TrimLeft函数,然后与5个空格拼接。或者,你可以设置一个自定义的UserControl,其中包含一个无边框的TextBox作为实际输入元素,叠加在另一个没有tabstop并且在聚焦时将焦点移至无边框元素上的 TextBox 上。


3

这个问题已经有了推荐答案。不过,我想提供另一种解决方案。在C#中为文本框添加填充可以使用“padLeft”方法。希望这对某些人有所帮助。

textBox1.Text = "Hello";
textBox1.Text = textBox1.Text.PadLeft(textBox1.Text.Length + 5);

or

textBox1.Text = textBox1.Text.PadLeft(textBox1.Text.Length + 5, '*');

1
很遗憾,这有一些不好的缺点。例如,一个人可以通过左边界删除键删除左填充。 :( - Christian
2
我发现这个解决方案非常有用,因为我正在使用只读文本框,所以不能进行退格操作。 - Anya Hope
2
@Christian 在这种情况下,您可以使用 TextChanged() 来在每次更改时设置 PadLeft。这样它就不会低于它了。 - C4d

1

我知道这有点老了。但这里有一个解决方案。对于初始文本,在开头添加一个空格。然后,您可以覆盖 OnKeyPress 事件并添加以下代码,以便您无法使用退格键。

protected override void OnKeyPress (KeyPressEventArgs e) {
   base.OnKeyPress (e);
   if (e.KeyChar == (char)Keys.Back && Text.Length == 1) e.Handled = true;
   else e.Handled = true;
}

你可以用空格的数量替换1来进行填充。

0

针对上面的回答和能够通过补位值进行退格的认为的缺点,可以使用文本框的SelectionStart属性来确定在TextChanged事件触发时光标的位置。

在此示例中,文本框在开头填充2个空格,以便显示的信息与其他使用填充属性的非输入控件对齐。

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        int pad = 2;
        int cursorPos = textBox1.SelectionStart;
        textBox1.Text = textBox1.Text.Trim().PadLeft(textBox1.Text.Trim().Length + pad);
        textBox1.SelectionStart = (cursorPos > pad ? cursorPos : pad);
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接