TextBox.TextAlign right-side alignment has no effect in certain conditions? - c#

I have a path selector in my Visual C# Express 2010 form application.
I do it using a FolderBrowserDialog and a (single line) TextBox, to show the selected path. Using the following line in my UI refresh code.
this.textBoxFolder.Text = this.folderBrowserDialog1.SelectedPath;
The ReadOnly property is set to true and TextAlign property is set to Right using the form designer, because the selected path is often longer than the TextBox, and I prefer to show the right-side of the path. The forms designer generates this:
//
// textBoxFolder
//
this.textBoxFolder.Location = new System.Drawing.Point(40, 72);
this.textBoxFolder.Name = "textBoxFolder";
this.textBoxFolder.ReadOnly = true;
this.textBoxFolder.Size = new System.Drawing.Size(160, 20);
this.textBoxFolder.TabIndex = 13;
this.textBoxFolder.TabStop = false;
this.textBoxFolder.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
Whenever the chosen path is shorter than the textbox size, the Right alignment works. (But this is not really important)
Whenever the chosen path is longer than the textbox size, the Right alignment has no effect, the string in the textbox is displayed such that the left-most character is visible, and right-most are hidden.
I know that in a normal single line TextBox (ReadOnly = false), when an overly-long string is typed in by hand, the right most chars are visible, even when focus goes away, regardless of whether TextAlign is set to Left / Right / Center!
In other words, my goal is, when TextBox.Text is programmatically set (as opposed to typed in), and the string is longer than the width of the TextBox, how do I get the right-most chars to be visible?

Instead of setting the TextAlign property, you should move the caret to the last character:
textBoxFolder.Text = this.folderBrowserDialog1.SelectedPath;
textBoxFolder.SelectionStart = textBox1.Text.Length - 1;
Setting SelectionStart actually moves the caret to the specified position. And that makes the character at that position visible in the TextBox.
If you can use a Label instead of a text box, you can use the one created by Hans Passant here that uses TextFormatFlags.PathEllipses flag while drawing the text.

Windows Mobile for Pocket PC, Windows Mobile for Smartphone, Windows CE Platform Note: In Pocket PC-based applications, a single-line text box supports only left alignment. A multiline text box can be aligned on the left, right, or center.

Related

Get the position (x,y) of the first character of the text within a text box in WPF

How to convert the first character index within the textbox to the x,y coordinates in WPF ie basically I need the point loaction of the first character of the text within a textbox in WPF.I am capturing the x,y coordinates of the textbox wrt image displayed on the window screen in wpf
UIElement container = (MainImage) as UIElement; System.Windows.Point relativeLocation = textboxinsert.TranslatePoint(new System.Windows.Point(0, 0), container);
But unaware to do it for text within a textbox in wpf.Any pointers would be really helpful?
If you only need to find the position of the first appearance, you will be fine with TextBox.Text.IndexOf('x');.
If you need to row too, you will need to make a difference between the lines that are broken because of the size of the textbox and the ones that are there because the user has pressed Enter.
You can do it by using a MemoryStream and a StreamReader.

Find the width/right coordinates of a TextBlock with dynamic text in WPF

I want to have a textblock with the user's name and right at the end of the string, an image to click and edit the name.
Since I can't control the name's length and I want it to follow the input string to the last character, I need to figure the width or the right border point of the text block.
I've tried Width (NaN) and ActualWidth (always 0) after setting the Text property, but it didn't work (tried UpdateLayout() as well).
The text is left aligned to another element so I can't right-align it.
How can I get the position of the right most part of the textblock with a dynamically input text in either code or XAML?
You can use ActualWidth property to get the width of TextBlock. But right after setting Text, the ActualWidth will not be updated immediately. One solution is to listen changes on ActualWidth of that TextBlock, and you will get the right value whenever it's changed
public MainWindow()
{
InitializeComponent();
DependencyPropertyDescriptor.FromProperty(TextBlock.ActualWidthProperty, typeof(TextBlock))
.AddValueChanged(textBlock1, (s, e) =>
{
var yourExpecedWidth = textBlock1.ActualWidth;
});
}

Vertically align text within a textbox when AutoSize=false

I'm trying to extend the standard TextBox control in the System.Windows.Forms namespace. One of the things I'm trying to accomplish is to modify padding on the top and bottom of the TextBox (the spacing between the text and the border).
Doing it on the left/right sides is pretty simple, but I'm having a hard time getting anything to work on the top/bottom.
Here are a couple of my requirements (if possible):
Avoid extending anything besides System.Windows.Forms.TextBox (no UserControls)
I want to keep MultiLine = false
This code allows me to resize vertically, and it adds a left padding:
public class TextBoxTest : TextBox
{
public TextBoxTest()
{
base.AutoSize = false;
NativeMethods.SendMessage(Handle, NativeMethods.EM_SETMARGINS, NativeMethods.EC_LEFTMARGIN, 20);
base.Height = 55;
base.Width = 150;
base.Text = "This is a test";
}
}
This will look like:
I also tried EM_SETRECT but it requires a MultiLine TextBox.
Is a top/bottom margin (or center vertically) possible - without using a UserControl and keeping MultiLine=false?
If so, can someone point me in the right direction?
UPDATE, to clarify, the reason I want to inherit from TextBox, and not a UserControl or Panel is so it passes the duck test (if it looks like a duck, quacks like a duck, etc). I want if (myControl is TextBox) ... to evaluate to true. There may be a way to do that, I haven't done much with Type Converters and maybe that's the path I should be taking.
I want this to be a true extension of a TextBox. In other words, it can do just about everything a textbox can do plus some, but no limitations due to the fact that it's not of type "TextBox". It seems like there's gotta be a way to adjust it somehow, it supports left and right margins but seemingly not upper/lower margins. Thanks again
You cannot change the padding property of Windows forms textbox from your code.
Instead you can place a textbox in a container, like a panel
remove the border of the textbox, make sure that the BackColor property for both is same
change the Dock property of the textbox to Fill
and then apply padding to the panel.

how to use a textbox but having an underscore line and blinking cursor?

I've created Windows forms and I'm using the textbox control for input, but I like to use it without border and other layout for textbox etc. I just want to use a underscore line and blinking cursor.
I played with the borderStyle (Fixed3D, None), backcolor=InactiveBorder etc. But I still do net get the underline... like this-> _____________ result like this: This is underline______________
I think Backcolor=InactiveBorder and BorderStyle=None is ok to use, but how to get the underline and blinking cursor?
Requirement:
blinking cursor and underline. (The doesn't blink by default, I just see a vertical line))
To fake this, you could add a label below the text box with the content being _____________________. My preferred solution would be to create a simple custom control that just draws a line.
Doesn't the caret on your system blink by default? It does on my system if the focus is on the text box.
If the caret doesn't blink by default, go to the Windows Control Panel and check your Keyboard Settings there - this is the place where you can adjust the caret blink rate.
For creating a underline for your textbox you can do like this,
First add a panel which is in the height of text box's height + underline's height.
Now add your textbox inside of that panel and set its dock to TOP.
Then set the textbox's border to none.
Now set the backcolor of the panel, according to the color need of underline.
Update:
This is VB code, i hope that you can easily convert it into c#
[ Concept: You just need to set the border for all of your textboxes as none.then In forms paint event track those text boxes and draw a line under it. ]
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles Me.Paint
Using xPen As Pen = New Pen(Color.Blue)
' Here we are using LINQ to filter the controls.
' If you don't want it, you just check all the controls by using typeof
' inside the For Each loop.
For Each xTxtBox In Me.Controls.OfType(Of TextBox)()
e.Graphics.DrawLine(xPen,
xTxtBox.Location.X,
xTxtBox.Location.Y + xTxtBox.Height,
xTxtBox.Location.X + xTxtBox.Width,
xTxtBox.Location.Y + xTxtBox.Height)
Next
End Using
End Sub
Use Masked TextBox and set Focus , e.g. maskedtextbox1.Focus(); <== this is for the blinking cursor and the masked textbox to the underline !
try :
To set logical focus to an input control
FocusManager.SetFocusedElement(this, textboxJack);
To set keyboard focus to an input control
Keyboard.Focus(textboxJill);
and for the masked textbox you can set a mask that will not be changed when you delete the text from it not like the simple textbox :)
Good luck
To do this, I would recommend creating a custom control (which is accomplished in the WinForms world by inheriting from one of the provided control classes). That custom control would then:
Provide its own drawing logic (by overriding OnPaint) in order to draw the underline and skip drawing anything else you don't want to see (e.g., the borders of the control).
Create its own caret when it receives the focus, and destroy that caret when it loses the focus. You'll find all the details on how to do this in my answer here.
You can also configure the blink rate of the caret by calling the SetCaretBlinkTime function. But note that this is not recommended, as it changes the global system setting and therefore affects other applications. It is best to do as Thorsten suggests and modify the setting on your machine if you wish to see something different. You should always respect a user's settings. There's a reason that they (or someone else) set up their system to not blink the caret.
Naturally, you will need to use P/Invoke to call these Win32 API functions related to caret management from a C# application. That shouldn't be too difficult if you know what you're doing. If you need a complete solution, consider setting a bounty on this question to persuade me to write one up for you.
I faced the same issue and built something that works fine:
public class TextBox : System.Windows.Forms.TextBox
{
public TextBox()
{
BorderStyle = BorderStyle.None;
Text = "__________"; //Sometime this doesn't work while creating the control in design mode ; don't know why
}
//protected override void OnFontChanged(EventArgs e)
//{
// base.OnFontChanged(e);
// RefreshHeight();
//}
bool loaded = false;
protected override void OnCreateControl()
{
if(!loaded)
RefreshHeight();
base.OnCreateControl();
}
private void RefreshHeight()
{
loaded = true;
Multiline = true;
Size s = TextRenderer.MeasureText(Text, Font, Size.Empty, TextFormatFlags.TextBoxControl);
MinimumSize = new Size(0, s.Height + 1);
Multiline = false;
}
}
I used bool loaded = false to avoid the app to crash in a loop because of OnCreateControl. TextBox control doesn't have OnLoad event (I'm open to another approach).
OnFontChanged can be uncommented if your app change the font size in run time
MinimumSize = new Size(0, s.Height + 1); I added 1 to avoid any error of MeasureText

Windows Forms RichTextBox cursor position

I have a C# Windows Forms program that has a RichTextBox control. Whenever the text inside the box is changed (other than typing that change), the cursor goes back to the beginning.
In other words, when the text in the RichTextBox is changed by using the Text property, it makes the cursor jump back.
How can I keep the cursor in the same position or move it along with the edited text?
Thanks
You can store the cursor position before making the change, and then restore it afterwards:
int i = richTextBox1.SelectionStart;
richTextBox1.Text += "foo";
richTextBox1.SelectionStart = i;
You might also want to do the same with SelectionLength if you don't want to remove the highlight. Note that this might cause strange behaviour if the inserted text is inside the selection. Then you will need to extend the selection to include the length of the inserted text.
Be careful, if someone refreshes or changes totally the RichTextBox content, the focus method must be invoqued previously in order to move the caret:
richTextBox1.Focus();
int i = richTextBox1.SelectionStart;
richTextBox1.Text = strPreviousBuffer;
richTextBox1.SelectionStart = i;
here's a smaller one, that has the same effect. this.richTextBox1.Select(this.richTextBox1.Text.Length, 0);
That marks 0 chars at the end of the text and sets the cursor to end

Categories