带底部边框的文本框 [英] TextBox with bottom border
问题描述
我想要带有下边框的 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 theColor.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屋!