c# how to place cursor at postion in richtextbox - c#

I have a richtextbox in WinForms and have created a copy and paste function and I can copy and paste at my cursor. HOWEVER, once have pasted my cursor moves to the start of the richtextbox. how do I get it to either stay at the position or move to the end of the pasted section?
I have tried
Point p = new Point(Cursor.Position.X, Cursor.Position.Y);
rtbNotePad.PointToClient(p); //but does not work.
private void copyToolStripMenuItem_Click(object sender, EventArgs e)
{
rtbNotePad.Copy();
}
private void pasteToolStripMenuItem_Click(object sender, EventArgs e)
{
string pasteText = Clipboard.GetText(TextDataFormat.Text).ToString();
Point p = new Point(Cursor.Position.X, Cursor.Position.Y);
if (Clipboard.ContainsText())
{
rtbNotePad.Text = rtbNotePad.Text.Insert(rtbNotePad.SelectionStart, Clipboard.GetText(TextDataFormat.Text).ToString());
rtbNotePad.PointToClient(p);
}
}

You should use the SelectionStart property to control the cursor position in ReachtextBox.
private void pasteToolStripMenuItem_Click(object sender, EventArgs e)
{
string pasteText = Clipboard.GetText(TextDataFormat.Text).ToString();
if (Clipboard.ContainsText())
{
var start = rtbNotePad.SelectionStart; // use this if you want to keep cursor where it was
//start += pasteText.Length; // use this if want to move cursor to the end of pasted text
rtbNotePad.Text = rtbNotePad.Text.Insert(rtbNotePad.SelectionStart, Clipboard.GetText(TextDataFormat.Text).ToString());
rtbNotePad.SelectionStart = start;
// rtbNotePad.Focus();
}
}

Related

Set the Caret/Cursor position in C# WPF when textbox clicked on

I am using a textbox for a login window. I want the textbox to display "Username" in light grey so the user knows to use that box to type in the username. Whenever the user clicks on the textbox even if it's in the middle of the word username I want the cursor to go to the first position and username will disappear when they start typing. I tried using the PreviewMouseDown event but it only works inside breakpoints but doesn't trigger at all outside it. Using the PreviewMouseUp event it works, but other caret positions can be selected before the cursor jumps to the beginning. I want it to appear like the user is unable to select any cursor position besides the first. This is the code I've tried.
private bool textboxuserfirstchange = true;
private void eventTextChanged(object sender, TextChangedEventArgs e)
{
if (textBoxUser.Text != "Username")
{
if (textboxuserfirstchange)
{
textBoxUser.Text = textBoxUser.Text[0].ToString();
textBoxUser.SelectionStart = 1;
textBoxUser.Opacity = 100;
}
textboxuserfirstchange = false;
}
}
private void eventPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
if (textboxuserfirstchange)
{
textBoxUser.Focus();
textBoxUser.Select(0, 0); //None of these working
textBoxUser.SelectionStart = 0;
textBoxUser.CaretIndex = 0;
}
}
You could for example handle the GotKeyboardFocus and PreviewTextInput event. Something like this:
private const string Watermark = "Username";
private void TextBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
if (textBoxUser.Text == Watermark)
textBoxUser.Dispatcher.BeginInvoke(new Action(() => textBoxUser.CaretIndex = 0), DispatcherPriority.Background);
}
private void textBoxUser_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
if (textBoxUser.Text == Watermark)
textBoxUser.Text = string.Empty;
}

Drag & Drop Label Text into TextBox using C#

I want to add text into textbox whenever label is drag and dropped inside textbox, so far i accomplished it using below methods. Consider i have already some text in textbox, now when i drop the label it adds the text to end, i understand it's because of i am adding textbox=textbox+labelcontents.
Is there any other way, to add text to that same location where it is being dropped, and all previous text remain same. Can we use location points?
In the form default Constructor:
lblBreakStartTime.MouseDown += new MouseEventHandler(lblBreakStartTime_MouseDown);
txtBoxDefaultEnglish.AllowDrop = true;
txtBoxDefaultEnglish.DragEnter += new DragEventHandler(txtBoxDefaultEnglish_DragEnter);
txtBoxDefaultEnglish.DragDrop += new DragEventHandler(txtBoxDefaultEnglish_DragDrop);
Mouse Down Event for label which will be dropped:
private void lblBreakStartTime_MouseDown(object sender, MouseEventArgs e)
{
DoDragDrop("START_TIME", DragDropEffects.Copy);
}
Textbox events:
private void txtBoxDefaultEnglish_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.Text)) e.Effect = DragDropEffects.Copy;
}
private void txtBoxDefaultEnglish_DragDrop(object sender, DragEventArgs e)
{
txtBoxDefaultEnglish.Text = txtBoxDefaultEnglish.Text + " " + "[" + (string)e.Data.GetData(DataFormats.Text) + "]";
txtBoxDefaultEnglish.SelectionStart = txtBoxDefaultEnglish.Text.Length;
}
Try this:
private void txtBoxDefaultEnglish_DragDrop(object sender, DragEventArgs e)
{
//Get index from dropped location
int selectionIndex = txtBoxDefaultEnglish.GetCharIndexFromPosition(txtBoxDefaultEnglish.PointToClient(new Point(e.X, e.Y)));
string textToInsert = string.Format(" [{0}]", (string)e.Data.GetData(DataFormats.Text));
txtBoxDefaultEnglish.Text = txtBoxDefaultEnglish.Text.Insert(selectionIndex, textToInsert);
txtBoxDefaultEnglish.SelectionStart = txtBoxDefaultEnglish.Text.Length;
//Set cursor start position
txtBoxDefaultEnglish.SelectionStart = selectionIndex;
//Set selction length to zero
txtBoxDefaultEnglish.SelectionLength = 0;
}

Drag and drop an to TextBox in a specific mouse position - Show caret or position indicator

I am pasting an item from a TreeView to a TextBox, but I want to paste that item in the mouse's current position and also show a caret like the image below.
Image with caret:
Here is my code:
private void tvOperador_ItemDrag(object sender, ItemDragEventArgs e)
{
var node = (TreeNode)e.Item;
if (node.Level > 0)
{
DoDragDrop(node.Text, DragDropEffects.Copy);
}
}
private void txtExpresion_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(string))) e.Effect = DragDropEffects.Copy;
}
private void txtExpresion_DragDrop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(System.String)))
{
string Item = (System.String)e.Data.GetData(typeof(System.String));
string[] split = Item.Split(':');
txtExpresion.Text += split[1];
}
}
This is tricky as the Drag&Drop operation keeps the mouse captured, so you can't use the mouse events..
One way is to set up a Timer to do the work..:
Timer cursTimer = new Timer();
void cursTimer_Tick(object sender, EventArgs e)
{
int cp = txtExpresion.GetCharIndexFromPosition(
txtExpresion.PointToClient(Control.MousePosition));
txtExpresion.SelectionStart = cp;
txtExpresion.SelectionLength = 0;
txtExpresion.Refresh();
}
The Timer uses the Control.MousePosition function to determined the cursor position every 25ms or so, sets the caret and updates the TextBox.
In your events you initialize it and make sure the TextBox has focus; finally you add the string at the current selection:
private void txtExpresion_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(string)))
{
e.Effect = DragDropEffects.Copy;
txtExpresion.Focus();
cursTimer = new Timer();
cursTimer.Interval = 25;
cursTimer.Tick += cursTimer_Tick;
cursTimer.Start();
}
}
private void txtExpresion_DragDrop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(System.String)))
{
cursTimer.Stop();
string Item = (System.String)e.Data.GetData(typeof(System.String));
string[] split = Item.Split(':');
txtExpresion.SelectedText = split[1]
}
}
A different way to solve it would be to not use normal Drag&Drop and only code the mouse events but this one worked ok a my first tests.
Update
While the above solution does work, using a Timer seems not exactly elegant. Much better to use the DragOver event, as seen in Reza's answer. But instead of painting a cursor, why not do the real thing, i.e. take control of the actual I-beam..?
The DragOver event is called all the time during the move so it works pretty much like MousMove would: So here is a merger of the two solutions, which I believe is the best way to do it:
private void txtExpresion_DragDrop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(System.String)))
{
string Item = (System.String)e.Data.GetData(typeof(System.String));
string[] split = Item.Split(':');
txtExpresion.SelectionLength = 0;
txtExpresion.SelectedText = split[1];
}
}
private void txtExpresion_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(string)))
{
e.Effect = DragDropEffects.Copy;
txtExpresion.Focus();
}
}
private void txtExpresion_DragOver(object sender, DragEventArgs e)
{
int cp = txtExpresion.GetCharIndexFromPosition(
txtExpresion.PointToClient(Control.MousePosition));
txtExpresion.SelectionStart = cp;
txtExpresion.Refresh();
}
You can draw a caret over TextBox in DragOver event. Also set the SelectionStart to the char index you get from mouse position. Then in DragDrop event, just set SelectedText.
private void textBox1_DragOver(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(System.String)))
{
var position = textBox1.PointToClient(Cursor.Position);
var index = textBox1.GetCharIndexFromPosition(position);
textBox1.SelectionStart = index;
textBox1.SelectionLength = 0;
textBox1.Refresh();
using (var g = textBox1.CreateGraphics())
{
var p = textBox1.GetPositionFromCharIndex(index);
g.DrawLine(Pens.Black, p.X, 0, p.X, textBox1.Height);
}
}
}
private void textBox1_DragDrop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(System.String)))
{
string txt = (System.String)e.Data.GetData(typeof(System.String));
textBox1.SelectedText = txt;
}
}

How we move a label when mouse click on it and when mouse key up then stop moving inside a group box

When is try with code, there appear two label and when move, screen become white from where they move. I want single label move with mouse move.
bool mDown = false;
private void label13_MouseMove(object sender, MouseEventArgs e)
{
if (mDown)
{
label13.Location = e.Location;
}
}
private void label13_MouseDown(object sender, MouseEventArgs e)
{
mDown = true;
}
private void label13_MouseUp(object sender, MouseEventArgs e)
{
mDown = false;
}
The e.Location gives you a mouse position relative to the control that is being clicked. So to fix that, instead of
label13.Location = e.Location;
use
var pos = this.PointToClient(Cursor.Position);
label13.Location = new Point(pos.X - offset.X, pos.Y - offset.Y);`
Create the offset variable as a property of the form (type Point) and initialize it on the mouse down event:
offset = e.Location;

How to recognize if a rectangle contains a Text block within in

I'm creating this program in which the user drags/drops a text block into a rectangle, and then store the contents of that specific textblock when he/she drops it into the rectangle.
I figured out how to do the drag/drop, but I just can't figure out how to check if the rectangle contains the textblock.
Here's the code so far:
bool captured = false;
double x_shape, x_canvas, y_shape, y_canvas;
UIElement source = null;
private void shape_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
source = (UIElement)sender;
Mouse.Capture(source);
captured = true;
x_shape = Canvas.GetLeft(source);
x_canvas = e.GetPosition(LayoutRoot).X;
y_shape = Canvas.GetTop(source);
y_canvas = e.GetPosition(LayoutRoot).Y;
}
private void shape_MouseMove(object sender, MouseEventArgs e)
{
if (captured)
{
double x = e.GetPosition(LayoutRoot).X;
double y = e.GetPosition(LayoutRoot).Y;
x_shape += x - x_canvas;
Canvas.SetLeft(source, x_shape);
x_canvas = x;
y_shape += y - y_canvas;
Canvas.SetTop(source, y_shape);
y_canvas = y;
}
}
private void shape_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
Mouse.Capture(null);
captured = false;
}
private void rectangle1_MouseEnter(object sender, MouseEventArgs e)
{
if (Mouse.Capture(null))
{
textBox1.Text = "test";
}
}
The "Shape" events apply to the textblock by the way, just for clarification.
I tried to find a shortcut and make it so with the rectangle1_MouseEnter event that if the mouse isn't clicked, then store the values (didn't include the code for the storing values). However, the problem is, this idea doesn't work because textBox1.Text="test" isn't registered, and I don't see why it isn't.

Categories