带底部边框的文本框 [英] TextBox with bottom border

查看:146
本文介绍了带底部边框的文本框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要带有下边框的 TextBox ,但是为 TextBox 绘制的图形在调整大小时会失真/损坏,因为 Color.Transparent



使用我发现的代码,我能够创建带下划线的TextBox(Drawn Rectangle with透明的顶部,左侧,右侧)。问题是当我调整窗体/窗口的大小时:当我调整到较小的尺寸时,再次调整大小以扩展它,绘制的图形失真。 ?任何修复该



下面是照片:第二张照片已被调整小,然后再返回到更大的尺寸。



以下是代码:

  [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;
颜色borderColor = Color.Black;
protected override void WndProc(ref Message m){
//我们必须改变客户端的大小来为边界
腾出空间//如果没有的话,边界会有多厚。
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);
}
}
如果(m.Msg == 0x85){// WM_NCPAINT
IntPtr的WDC = GetWindowDC(手柄);
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.Transparent 我通过将其更改为Color.White来修复它,因为我有一个白色背景。但是,情况并非总是如此,在使用Color.Transparent时,如何防止闪烁/撕裂?

解决方案

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

 使用System.Drawing中; 
使用System.Windows.Forms;
public class MyTextBox:TextBox
{
public MyTextBox()
{
BorderStyle = System.Windows.Forms.BorderStyle.None;
AutoSize = false; //允许你改变高度以使底部填充
Controls.Add(new Label()
{Height = 1,Dock = DockStyle.Bottom,BackColor = Color.Black});
}
}


I want to have TextBox with bottom border but Graphics drawn for TextBox is distorted/broken on resize because of Color.Transparent.

Using an code I found, I was able to create a underlined TextBox (Drawn Rectangle with tranparent top, left, right). The problem is when I resize the form/window: when I resize it to smaller, then resize again to expand it, the graphics drawn is distorted. Any fix for this?

Here are photos: The second photo has been already resized smaller, then back to a larger size.

Here's the code:

[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);
    }


EDIT :

I already found the issue, it's because of the Color.Transparent I fixed it by changing it to Color.White, since I have a white background. But then, that would not always be the case, how would I prevent that "Flickering/Tearing" while using Color.Transparent?

解决方案

To have a TextBox with bottom border, The most simple workaround that I can offer is docking a 1 pixel height lable (or other control) to bottom of the TextBox:

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 });
    }
}

这篇关于带底部边框的文本框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆