3

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. NormalContracted then Expanded

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?

2
  • TextBox doesn't like being drawn on; the graphics will be wiped out pretty much immediately and all those tricks only help so much.. The effect you see is called 'tearing'. You'd better create a real form with Labels and plain TextBoxes.. Commented Jul 15, 2016 at 19:14
  • Transparency is not really supported in Winforms. TextBox doesn't support it at all. Commented Jul 15, 2016 at 19:29

2 Answers 2

11

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 }); } } 
Sign up to request clarification or add additional context in comments.

8 Comments

@Yawz I saw your edit. You can use White color to render those invisible borders, but It also makes flickering when you move mouse over the control. Currently I prefer to use this workaround which I shared.
This doesn't answer directly my question, but it's a solves my problem in a different approach, but how can I create a padding for the text? See this Screenshot: oi67.tinypic.com/10zvgqu.jpg I hope to give it padding on right and left sides, and a margin to raise the text..
For padding between Text and Line: it's enough to set AutoSize property in constructor to false. For setting left padding and right padding, you should send EM_SETMARGINS message to the TextBox. You will find this post helpful: NumericUpDown with Unit I've set left padding in answer, and in comments added right padding too.
I'm a newbie and literally don't know how to use that code to give my text box a left and right margin, anyways I will accept this. Here's my code where I don't know how to implement the left and right padding for the text.. pastebin.com/3AgtNZqx I am hoping for a result like this: imgur.com/2In0DQB .. I tried but I can't implement, I hope you have a solution for this..
@HmH TextBox.Controls[0] is the label. You can also create a public property to expose it.
|
0
 this.TxtBox.BorderStyle = System.Windows.Forms.BorderStyle.None; 

1 Comment

Answer needs supporting information Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.