C# 带底部边框的文本框

C# 带底部边框的文本框,c#,winforms,user-interface,graphics,window-resize,C#,Winforms,User Interface,Graphics,Window Resize,我想让TextBox具有底部边框,但是为TextBox绘制的图形在调整大小时会扭曲/损坏,因为颜色。透明的 使用我找到的代码,我能够创建一个带下划线的文本框(用tranparent top、left、right绘制的矩形)。问题是当我调整窗体/窗口的大小时:当我将其调整为更小的大小,然后再次调整大小以展开它时,绘制的图形会扭曲对此有任何修复吗? 以下是照片:第二张照片的大小已经变小,然后又变大。 代码如下: [DllImport("user32")] private static ex

我想让
TextBox
具有底部边框,但是为
TextBox
绘制的图形在调整大小时会扭曲/损坏,因为
颜色。透明的

使用我找到的代码,我能够创建一个带下划线的文本框(用tranparent top、left、right绘制的矩形)。问题是当我调整窗体/窗口的大小时:当我将其调整为更小的大小,然后再次调整大小以展开它时,绘制的图形会扭曲对此有任何修复吗?

以下是照片:第二张照片的大小已经变小,然后又变大。

代码如下:

[DllImport("user32")]
    private static extern IntPtr GetWindowDC(IntPtr hwnd);
    struct RECT {
        public int left, top, right, bottom;
    }
    struct NCCALSIZE_PARAMS {
        public RECT newWindow;
        public RECT oldWindow;
        public RECT clientWindow;
        IntPtr windowPos;
    }

    float clientPadding = 0;
    int actualBorderWidth = 2;
    Color borderColor = Color.Black;
    protected override void WndProc(ref Message m) {
        //We have to change the clientsize to make room for borders
        //if not, the border is limited in how thick it is.
        if (m.Msg == 0x83) { //WM_NCCALCSIZE 
            if (m.WParam == IntPtr.Zero) {
                RECT rect = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT));
                rect.left += 2;
                rect.right -= 2;
                rect.top += 0;
                rect.bottom -= 0;// (int)clientPadding;
                Marshal.StructureToPtr(rect, m.LParam, false);
            } else {
                NCCALSIZE_PARAMS rects = (NCCALSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(NCCALSIZE_PARAMS));
                rects.newWindow.left += (int)clientPadding;
                rects.newWindow.right -= (int)clientPadding;
                rects.newWindow.top += (int)clientPadding;
                rects.newWindow.bottom -= 2;
                Marshal.StructureToPtr(rects, m.LParam, false);
            }
        }
        if (m.Msg == 0x85) {//WM_NCPAINT    
            IntPtr wDC = GetWindowDC(Handle);
            using (Graphics g = Graphics.FromHdc(wDC)) {
                ControlPaint.DrawBorder(g, new Rectangle(0, 0, Size.Width, Size.Height),
                    Color.Transparent, 1, ButtonBorderStyle.Solid,
                    Color.Transparent, 1, ButtonBorderStyle.Solid,
                    Color.Transparent, 1, ButtonBorderStyle.Solid,
                    borderColor, actualBorderWidth, ButtonBorderStyle.Solid);
            }
            return;
        }
        base.WndProc(ref m);
    }

编辑:我已经发现了问题,这是因为
颜色是透明的
我将其更改为Color.White,因为我有白色背景。但是,情况并非总是如此,我如何防止在使用Color.Transparent时出现“闪烁/撕裂”现象?

要使用底部边框,我可以提供的最简单的解决方法是将一个1像素高的标签(或其他控件)固定到
文本框的底部:

using System.Drawing;
using System.Windows.Forms;
public class MyTextBox : TextBox
{
    public MyTextBox()
    {
        BorderStyle = System.Windows.Forms.BorderStyle.None;
        AutoSize = false; //Allows you to change height to have bottom padding
        Controls.Add(new Label()
                    { Height = 1, Dock = DockStyle.Bottom, BackColor = Color.Black });
    }
}

文本框不喜欢被画上;图形将很快消失,所有这些技巧只会起到很大的作用。。你看到的效果叫做“撕裂”。你最好创建一个带有标签和普通文本框的真实表单。Winforms不支持透明。文本框根本不支持它。@Yawz我看到了你的编辑。您可以使用白色来渲染这些不可见的边框,但当您将鼠标移到控件上时,它也会使边框闪烁。目前,我更喜欢使用我共享的解决方案。这并不能直接回答我的问题,但这是一个用不同的方法解决我的问题的方法,但我如何才能为文本创建填充?请参见此屏幕截图:我希望在左右两侧加上填充,并在文本和行之间加上边距。·对于文本和行之间的填充:将构造函数中的
AutoSize
属性设置为false就足够了。•要设置左填充和右填充,应将EM_SETMARGINS消息发送到
文本框
。你会发现这篇文章很有帮助:我在答案中设置了左空格,在评论中也添加了右空格。我是一个新手,不知道如何使用这些代码来给我的文本框设置左空格和右空格,无论如何我都会接受。下面是我的代码,我不知道如何实现文本的左右填充。。我希望有这样的结果:。。我尝试过,但无法实现,我希望您能找到解决方案。@HmH
TextBox.Controls[0]
是标签。还可以创建公共属性以公开它。