2

I'm using a DragEventArgs for a Drop Event and have the x, y Drop Insert position within a TextBox.

How do you convert the x, y to and Index within the TextField? I is extremely import for me to find out this inormation!

Thank you very much!

Fredrik Hedblad
  • 83,499
  • 23
  • 264
  • 266
user565660
  • 1,171
  • 3
  • 20
  • 37
  • 1
    To clarify: Do you intend that if, for example, you had the string `"California"` in a TextBox, and dropped something in between the `'i'` and the `'f'`, that it would insert that object at index 4 of the Text field? – Dan J Jan 06 '11 at 20:31
  • I'm using a PreviewDrop and want to peice together in the correct positions the Old text with the attempted drop text. Yes that is correct. I won't acutally set the value myself, I will either set the DragEventArgs.Handled to true or not – user565660 Jan 06 '11 at 20:39

2 Answers2

3

You need to use the GetCharacterIndexFromPoint method of the TextBox:

void textBox1_Drop(object sender, DragEventArgs e)
{
    TextBox textBox = (TextBox)sender;
    Point position = e.GetPosition(textBox);
    int index = textBox.GetCharacterIndexFromPoint(position, true);
    string text = (string)e.Data.GetData(typeof(string));
    textBox.SelectionStart = index;
    textBox.SelectionLength = 0;
    textBox.SelectedText = text;
}
Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
  • Thank you very much for response. I tried the code and GetCharacterIndexFromPoint always returns -1 or it couldn't find it. Is there some kind of offset that you need to do? – user565660 Jan 06 '11 at 21:38
  • @user565660, I realize I forgot the `snapToText` parameter in the code above (I fixed it). Do you still get -1 if you pass `true` for this parameter? What is the value of `position`? You don't need an offset, because the position is already relative to the `TextBox` (as specified in the call to `GetPosition`) – Thomas Levesque Jan 06 '11 at 22:31
3

Here is a small enhancement that calculates the position index of a character that is closest to the dropping point. The GetCharacterIndexFromPoint method actually does not return the position of the closest char (like it's documented), but it returns the index of the character that is under the dropped point (even if the dropped point is right next to the right edge of the char, in which case the method should return the index of the next char which is actually closer to the dropping point).

private int GetRoundedCharacterIndexFromPoint(TextBox textBox, Point dropPoint)
{
    int position = textBox.GetCharacterIndexFromPoint(dropPoint, true);

    // Check if the dropped point is actually closer to the next character
    // or if it exceeds the righmost character in the textbox
    // (in this case increase position by 1)
    Rect charLeftEdge = textBox.GetRectFromCharacterIndex(position, false);
    Rect charRightEdge = textBox.GetRectFromCharacterIndex(position, true);
    double charWidth = charRightEdge.X - charLeftEdge.X;
    if (dropPoint.X + charWidth / 2 > charRightEdge.X) position++;

    return position;
}
jurev
  • 1,457
  • 1
  • 14
  • 22