的方法GetPositionFromCharIndex()
和GetCharIndexFromPosition()
有兩個限制:
- 他們不超出文本框
- 的邊框文字工作的
TextBox.SelectionStart
的字符索引是在結束一個插入符號相同在下一行開始處插入一行字符和一個插入符號。
要解決這個問題,您可以:
- 滾動文本框使用方法說之前顯示相關行。
- 使用user32.dll中的GetCaretPos函數將其與SelectionStart的位置進行比較。如果它們不相等,則意味着脫字符號在行尾。
- 模擬{END}鍵將光標定位在行尾。
我遇到的另一個問題是,TextBox.Lines
指的是由新行字符分隔邏輯線路,而功能TextBox.GetLineFromCharIndex()
和TextBox.GetFirstCharIndexFromLine()
指視線,因爲它們被顯示在文本框(即,從一邊到文本框的側,而不必有新行字符)。不要混淆。
生成的代碼(醜,你可以要求,但工作)如下:
class Utils
{
[DllImport("user32.dll")]
static extern bool GetCaretPos(out System.Drawing.Point lpPoint);
public static void LineUp(TextBox tb)
{
int oldCharIndex = tb.SelectionStart;
int oldLineNo = tb.GetLineFromCharIndex(oldCharIndex);
System.Drawing.Point oldCharPos = tb.GetPositionFromCharIndex(oldCharIndex);
System.Drawing.Point oldCaretPos;
if (GetCaretPos(out oldCaretPos))
{
if (oldCharPos == oldCaretPos)
{
if (oldLineNo > 0)
{
tb.SelectionStart = tb.GetFirstCharIndexFromLine(oldLineNo - 1);
tb.ScrollToCaret();
System.Drawing.Point newPos = new System.Drawing.Point(oldCaretPos.X, oldCaretPos.Y - tb.Font.Height);
int newCharIndex = tb.GetCharIndexFromPosition(newPos);
if (tb.GetPositionFromCharIndex(newCharIndex).Y == newPos.Y)
{
tb.SelectionStart = newCharIndex;
}
else
{
tb.SelectionStart = tb.GetFirstCharIndexFromLine(oldLineNo - 1);
System.Windows.Forms.SendKeys.Send("{END}");
}
}
}
else
{
if (oldLineNo > 1)
{
tb.SelectionStart = tb.GetFirstCharIndexFromLine(oldLineNo - 2);
tb.ScrollToCaret();
System.Drawing.Point newPos = new System.Drawing.Point(oldCaretPos.X, oldCaretPos.Y - tb.Font.Height);
int newCharIndex = tb.GetCharIndexFromPosition(newPos);
if (tb.GetPositionFromCharIndex(newCharIndex).Y == newPos.Y)
{
tb.SelectionStart = newCharIndex;
}
else
{
tb.SelectionStart = tb.GetFirstCharIndexFromLine(oldLineNo - 2);
System.Windows.Forms.SendKeys.Send("{END}");
}
}
}
}
}
public static void LineDown(TextBox tb)
{
int oldCharIndex = tb.SelectionStart;
int oldLineNo = tb.GetLineFromCharIndex(oldCharIndex);
System.Drawing.Point oldCharPos = tb.GetPositionFromCharIndex(oldCharIndex);
System.Drawing.Point oldCaretPos;
if (GetCaretPos(out oldCaretPos))
{
if (oldCharPos == oldCaretPos)
{
if (oldLineNo < tb.GetLineFromCharIndex(tb.Text.Length - 1))
{
tb.SelectionStart = tb.GetFirstCharIndexFromLine(oldLineNo + 1);
tb.ScrollToCaret();
System.Drawing.Point newPos = new System.Drawing.Point(oldCaretPos.X, oldCaretPos.Y + tb.Font.Height);
int newCharIndex = tb.GetCharIndexFromPosition(newPos);
if (tb.GetPositionFromCharIndex(newCharIndex).Y == newPos.Y)
{
tb.SelectionStart = newCharIndex;
}
else
{
tb.SelectionStart = tb.GetFirstCharIndexFromLine(oldLineNo + 1);
System.Windows.Forms.SendKeys.Send("{END}");
}
}
}
else
{
System.Drawing.Point newPos = new System.Drawing.Point(oldCaretPos.X, oldCaretPos.Y + tb.Font.Height);
int newCharIndex = tb.GetCharIndexFromPosition(newPos);
if (tb.GetPositionFromCharIndex(newCharIndex).Y == newPos.Y)
{
tb.SelectionStart = newCharIndex;
}
else
{
tb.SelectionStart = tb.GetFirstCharIndexFromLine(oldLineNo);
System.Windows.Forms.SendKeys.Send("{END}");
}
}
}
}
}
信用爲理念去this answer,你也可能想看看MSDN reference on GetCaretPos和other Caret functions。
來源
2012-06-22 16:19:41
Dil
模擬'KeyPress'。 –
請指定您是否使用Windows窗體,WPF或其他。如果一切都失敗了,就像Kendall所說的那樣,根據情況爲上下箭頭生成一個KeyPress事件。 –
Winforms和模擬KeyPress在這種情況下將不起作用,因爲我試圖模擬DataGridView中的文本框單元格中的正常文本框行爲 - 請參閱[this](http://stackoverflow.com/questions/11108791/edit- a-textbox-cell-in-datagridview-as-if-it-a-normal-textbox-no-jumping-o) – Dil