Specifically, what I'd like is to have a user right-click in a TextBox, figure out and save the index position within the text where the right-click occurred, and then later insert some text at that position once the user makes a choice from the context menu that pops up because of the right click.
The tricky part is getting the index position based on the coordinates of the right-click.
This is in Silverlight 4.
private int _insertPoint;
private void userNotification_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
// Move and open the context menu relative to its container.
contextMenu.Horizontal开发者_如何学COffset = e.GetPosition(container).X;
contextMenu.VerticalOffset = e.GetPosition(container).Y;
contextMenu.IsOpen = true;
// Get the click coordinates relative to the TextBox.
int clickX = e.GetPosition(textBox).X;
int clickY = e.GetPosition(textBox).Y;
_insertPoint = ?; // Here's the problem.
}
private void SelectFieldToInsert(object sender, MouseButtonEventArgs e)
{
// Close the context menu.
contextMenu.IsOpen = false;
var item = sender as ListBoxItem;
textBox.Text = textBox.Text.Insert(_insertPoint, "<" + item.Content + ">");
}
The TextBox.SelectionStart property on a textbox should help you. From the link:
If there is no selection, the SelectionStart value gets or sets the location of the cursor.
How about:
// Get the click coordinates relative to the TextBox.
int clickX = (int)e.GetPosition(textBox).X;
int clickY = (int)e.GetPosition(textBox).Y;
int startPosition = 0;
double currentHeight = 0;
double calculatedHeight = 0;
int charIndex;
TextBlock tb = new TextBlock();
tb.Width = this.textBox.Width;
tb.FontFamily = this.textBox.FontFamily;
tb.FontSize = this.textBox.FontSize;
for (charIndex = 0; charIndex < this.textBox.Text.Length; charIndex++)
{
tb.Text = this.textBox.Text.Substring(startPosition, charIndex - startPosition + 1);
if (tb.ActualHeight > currentHeight)
{
if (currentHeight == 0)
{
currentHeight = tb.ActualHeight;
calculatedHeight = currentHeight;
}
else
{
startPosition = charIndex + 1;
charIndex++;
tb.Text = this.textBox.Text.Substring(startPosition, charIndex - startPosition + 1);
currentHeight = tb.ActualHeight;
calculatedHeight += currentHeight;
}
}
if (tb.ActualWidth > clickX && calculatedHeight > clickY) break;
}
_insertPoint = charIndex;
I won't lie and say it's elegant, but it appears to work reasonably well.
精彩评论