Drag & Drop Label Text into TextBox using C# - 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;
}

Related

Track the last two focus Textboxes

I have a certain number of Textboxes, I need to track the last two focused Texboxes. This is the approch that I attempted.
private Control _focusedControl;
private Control _lastfocusedControl;
private void PCp1txt_LostFocus(object sender, System.EventArgs e)
{
_lastEnteredControl = (Control)sender;
}
private void PCp1txt_LostFocus(object sender, System.EventArgs e)
{
_lastEnteredControl = (Control)sender;
}
private void PCp2txt_GotFocus(object sender, EventArgs e)
{
_focusedControl = (Control)sender;
}
private void PCp2txt_GotFocus(object sender, EventArgs e)
{
_focusedControl = (Control)sender;
}
This is not working because when I press the button the contenent of the _lastfocusedControl will be the same as _focusedControl because another control was focused by clicking that button.
You can handle Enter event of all those TextBox controls using a single handler and in the handler and keep track of last n focused TextBox controls:
const int n = 2;
TextBox[] textBoxes = new TextBox[n];
private void textBox_Enter(object sender, EventArgs e)
{
var destination = new TextBox[n];
Array.Copy(textBoxes, 1, destination, 0, textBoxes.Length - 1);
textBoxes = destination;
textBoxes[textBoxes.Length - 1] = (TextBox)sender;
}
In above example, we are shifting the array to left, then assign the sender to the last element. This way the array always contains the last n focused TextBox controls for you.
I would suggest, to make it simpple, do something like when your textbox get focused, put the name of it into an array, for example, and after that, list the last two name added of the array created.

c# how to place cursor at postion in richtextbox

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();
}
}

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 to randomize the text in a label

How to read a random line from a text file and change the text in the label to be that random line, then after a drag and drop which i have coded(below) the label will change the text. The language is c#. I am a beginner so i apologize if this is a stupid question.
private void txt_carbs_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.Text))
e.Effect = e.AllowedEffect;
// check if the held data format is text
// if it is text allow the effect
else
e.Effect = DragDropEffects.None;
// if it is not text do nothing
}
private void txt_protien_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.Text))
e.Effect = e.AllowedEffect;
// check if the held data format is text
// if it is text allow the effect
else
e.Effect = DragDropEffects.None;
// if it is not text do nothing
}
private void txt_fats_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.Text))
e.Effect = e.AllowedEffect;
// check if the held data format is text
// if it is text allow the effect
else
e.Effect = DragDropEffects.None;
// if it is not text do nothing
}
private void txt_fats_DragDrop(object sender, DragEventArgs e)
{
txt_fats.Text += e.Data.GetData(DataFormats.Text).ToString();
//add the text into the text box
}
private void txt_protien_DragDrop(object sender, DragEventArgs e)
{
txt_protien.Text += e.Data.GetData(DataFormats.Text).ToString();
//add the text into the text box
}
private void txt_carbs_DragDrop(object sender, DragEventArgs e)
{
txt_carbs.Text += e.Data.GetData(DataFormats.Text).ToString();
//add the text into the text box
}
private void lbl_term_MouseDown(object sender, MouseEventArgs e)
{
lbl_term.DoDragDrop(lbl_term.Text, DragDropEffects.Copy);
// get the text from the label
}
Also this is how ive been changing the labels text however this isn't it isn't randomized
StreamReader score =
new StreamReader(file_location);
label10.Text = score.ReadLine();
Not the most efficient implementation in the world, but you could do the following to get a random line from a file, if the file isn't too big, as described in this answer here:
string[] lines = File.ReadAllLines(file_location);
Random rand = new Random();
return lines[rand.Next(lines.Length)];

How do I keep words from being replaced by each button?

I am creating an application for class called Sentence Builder, it's supposed to allow the user to click the buttons provided to build a sentence on a label. I have had no success on getting a word generated by a button to stay on the label after I click another button. When I click a button it displays the word on the button onto the label. Then when I click another button, the word on that button appears on the label but it takes the place of the previous word that was already there. I need it to stay on the label so the user can create a sentence on the label by pressing multiple buttons. This is my code for the application.
namespace C3_7_Sentence_Builder
{
public partial class sentencebuilderForm : Form
{
public sentencebuilderForm()
{
InitializeComponent();
}
private void resetButton_Click(object sender, EventArgs e)
{
sentenceoutputLabel.Text = "";
}
private void exitButton_Click(object sender, EventArgs e)
{
this.Close();
}
private void AButton_Click(object sender, EventArgs e)
{
string output;
output = AButton.Text;
sentenceoutputLabel.Text = output;
}
private void a_Button_Click(object sender, EventArgs e)
{
string output;
output = a_Button.Text;
sentenceoutputLabel.Text = output;
}
private void anButton_Click(object sender, EventArgs e)
{
string output;
output = anButton.Text;
sentenceoutputLabel.Text = output;
}
private void TheButton_Click(object sender, EventArgs e)
{
string output;
output = TheButton.Text;
sentenceoutputLabel.Text = output;
}
private void the_Button_Click(object sender, EventArgs e)
{
string output;
output = the_Button.Text;
sentenceoutputLabel.Text = output;
}
}
}
you need to use +=
sentenceoutputLabel.Text += output;
what that does is it appends the string instead of overwrites it.
Aside from my comment, I figured I would post as an answer because you can remove all the individual events and suscribe all your buttons to the following to do the same thing.
private void sentence_button_clicked(object sender, EventArgs e)
{
var button = sender as Button;
if(button != null)
sentenceoutputLabel.Text += button.Text;
}
The only button that does need to reassign the text, instead of appending would be the Reset button.
You are always replacing all text of the label with all text of your choice. You need the text of the label to stay and only add the new text:
sentenceoutputLabel.Text = sentenceoutputLabel.Text + output;
You may want to add some spaces:
sentenceoutputLabel.Text = sentenceoutputLabel.Text + " " + output;

Categories