I ahve a RTB with sufficent text that scrolling is needed
user enters a string and I highlight all occurrences using a combination of Find and Select which is great but now I want the ability for a user to press Next and the next higlighted instance should be visible say 2at /3rd of the bounding rectangle ( I would even settle for at the top of the bound.
How do I scroll to an index basically ( I am caching the indices as I find and markup )
oh also this is C# Winforms .NET 2.0
Set the selection start to the next location, and then use ScrollToCaret to scroll to that location in the rich text box.
rText1.SelectionStart = i
rText1.ScrollToCaret()
private void myrichTextBox_TextChanged(object sender, EventArgs e)
{
myrichTextBox.SelectionStart = myrichTextBox.Text.Length; //Set the current caret position at the end
myrichTextBox.ScrollToCaret(); //Now scroll it automatically
}
Related
I have a Windows Forms project that sets button text based on variables. The font is quite large for readability, but it means that some words are too long to fit in the button nicely, and the last few characters break onto multiple lines.
Is there an algorithm or property I can use to resize the text inside the button to prevent this from happening?
I don't want to try to fit the text on one line, I just want to stop the text from splitting words up.
If you really want to resize the font, you could try to detect when the text has reached the bounds of the button and then reduce the font size. Here's some code to get you started, but I'm not sure how to determine the length where text will start wrapping based on the button width. Perhaps there's some other property for that which I couldn't find.
// Get some info from the button control
var graphics = button1.CreateGraphics();
var font = button1.Font;
var textWidth = graphics.MeasureString(button1.Text, font).Width;
// Not sure what the magic formula is to determine when the word wraps
if (textWidth > button1.Width - 25)
{
// Assign a new font based on the old one, but smaller
button1.Font = new Font(font.FontFamily, font.Size - 1,
font.Style, GraphicsUnit.Pixel);
}
Set the AutoSize of the button to "false":
Button1.AutoSize = "false"
white-space: -moz-pre-wrap; /* Firefox */
white-space: -o-pre-wrap; /* Opera */
white-space: pre-wrap; /* Chrome */
word-wrap: break-word; /* IE */
I am not sure, but there should not be any algorithm which can help you here (even AI algorithms). Constraint is you want to keep font size and button size same. However you can do following which could solve your problem.
Use abbreviated text. e.g. First few words(characters)/ Initials of text. Generally contacts list on android mobiles, skype, or any other communicator shows initials if avatar is not set.
Show some part of text on button and when mouse hovers then show full text by resizing the button or on tooltip.
Add some space on form which will show full text when mouse is hovered on any button on it. So a common label on form which will show full button text when mouse is hovered on any button.
If texts are fixed/static then introduce some icons on button instead of text and show full text as tooltip.
~Nilesh
I need to set Selection start of a text box based on the mouse position, i tried to load the text box on Double Click, once the text box is loaded, i need to set the selection start based on the Mouse position. (i.e) if a text box contains some values like "abcdef", if the mouse cursor is near "c" when textbox is loaded, then the selection start should be after "c".
I have also tried this
textBox.GetCharIndexFromPosition(e.Location);
but i didn't get it right,
Thanks in advance.
Regards,
Venkatesan R
Putting #Reza's code in the correct event will work just fine:
private void textBox_MouseDoubleClick(object sender, MouseEventArgs e)
{
textBox.Text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; // load the text data here
// now position the caret onto the mouse position
textBox.SelectionStart = textBox.GetCharIndexFromPosition(e.Location);
// and clear a selection
textBox.SelectionLength = 0;
}
Note that you need to use the MouseDoubleClick, not the simple DoubleClick or else you miss the e.Location param!
This is the simplest and most direct way to get the mouse coordinates relative to the TextBox.
If your loading method is complex you can call it by passing in the MouseEventArgs e but simply calling it instead of the textBox.Text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; is the most natural way.
If you want to you could also use
textBox.SelectionStart = textBoxtextBox1.PointToClient(Control.MousePosition));
This will work in any event or method. PointToClient will calulate the relative position from the screen position Control.MousePosition.
After setting the SelectionStart and SelectionLength, the Caret is at the end of the selection.
How can I move the Caret to the beginning of the selection?
I now tried this: The question is not answered by the other threads
SelectionStart = selStart; // set the desired position
SelectionLength = 0;
MyLibs.WindowsDll.POINT point;
MyLibs.WindowsDll.GetCaretPos(out point); // save the position
SelectionLength = restOfWord.Length; // extend the selection
MyLibs.WindowsDll.SetCaretPos(point.X, point.Y); // restore caret position
GetCaretPos and SetCaretPos are working somehow, but not as it should.
Using the above code snippet, the caret is indeed blinking at the beginning of the selection.
But ... then I hit backspace or cursor left/right, the caret still behaves like it is still at the end of the selection.
Unfortunately, you can not do this using managed code like C#,
but to achieve this goal you may use C++, SetFocus() function,
for example:
//use SetFocus()
pEdit->SetFocus()
//place caret at the end:
pEdit->SendMessage (WM_KEYDOWN,VK_END,0);
//simulate keyup:
m_Edit->SendMessage (WM_KEYUP,VK_END,0);
//send the key code:
m_Edit->SendMessage(WM_CHAR,'A',0);
Have a look to MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/ms646312(v=vs.85).aspx
You may use also CEdit::SetSel to accomplish that:
CEdit* e = (CEdit*)GetDlgItem(IDC_EDIT1);
e->SetFocus();
e->SetSel(0,-1); // move cursor at the end
e->SetSel(-1); // remove selection
See details in Stackoverflow question: CEdit control MFC, placing cursor to end of string after SetWindowText
UPDATED:
If you need to set position to the beginning you can reset the Caret position to start before displaying the text using:
SetSel (0,0);
You can not move the caret to the beginning while keeping the text selected using basic C#/C++ functions, however you can override basic "Caret" logic using C++ or/and Assembler.
I am trying to get which of the * is clicked in text of label as in picture.
NOTE : Number of * is not known at first.User inputs it.So the position of mouse click is not useful.
Answer is :
X of first *'s location is known, equals = 10 .The asterisks are spaced equally,distance between two * is ~15 pixel .
When user clicks on one of asterisks , index of asterisks can be calculated as the code below
private void label4_MouseDoubleClick(object sender, MouseEventArgs e)
{
double t = (e.X - 10) / 15.0;
int indexOfClickedAsterisk=(int)Math.Round(t) + 1;
}
It depends. If you are willing to display the text in a TextBox instead of Label (which is what it looks like you're using now), then you can use the GetCharIndexFromPosition method. Just make sure you specify the Point in client coordinates (comes for free if you are handling mouse clicks in the Label control itself).
Note that you can set the TextBox as ReadOnly, assuming you don't want the user actually modifying the text. They will still be able to select the text though.
If you need an actual Label control (e.g. you don't even want selectable text and the grayed-out appearance of a disabled TextBox isn't appropriate), then you'll have to write your own (or find one online that someone else wrote already), as the built-in one doesn't have that functionality. It would not be too difficult. You can use the TextRenderer methods to determine where each character is laid out when drawn and then use that information to correlate character positions with mouse clicks.
I'm concatenating a string that sometimes is long enough for it not to fit in a label control. How can i make it autoscroll to the rightside so i always see the end of the string?
While I'm sure there are ways of doing, I have to ask, why? I think it would look and/or work very badly and probably confuse the user.
Why not have the text get trimmed with an ellipse (...) at the end and show a tooltip on the label?
using System.Windows.Forms;
var label = new Label();
label.AutoSize = false;
label.AutoEllipsis = true;
label.Text = "This text will be too long to display all together.";
var labelToolTip = new ToolTip();
labelToolTip.SetToolTip(label, label.Text);
Now the tooltip will show the full text when the user hovers over it. Since the text in the label will be truncated and end in an ellipse, the user should know to hover over for more info (usually the standard way).
The TextAlign property allows you to specify the alignment. If you right-justify it with this, the right side of the text will always be visible. However, if you want it to be left or center justified and still have the behavior you describe, I suspect you will need to perform some measurement using Graphics.MeasureString to determine if the text fits and change the alignment dynamically.
AFAIK there's no way to scroll a label. A hack would be to use a TextBox (read-only, turn off border) then use SendKeys.Send() to move the cursor to the end of the text. Something like:
textBox1.Focus();
SendKeys.SendWait("{END}");
To get the text to not show up as selected I had to change it's position in the tab order (so that it wasn't 1) but that may not be a problem in your case.