如何使用alt + arrow_up和alt + arrow_down向上/向下移动一条线 [英] How to move a line up / down with alt + arrow_up and alt + arrow_down

查看:107
本文介绍了如何使用alt + arrow_up和alt + arrow_down向上/向下移动一条线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
       If e.KeyCode = Keys.Down Then
          movelineup()
       ElseIf e.KeyCode = Keys.Up Then
           movelinedown()
       End If
   End Sub

   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
       Me.KeyPreview = True
   End Sub





我尝试了什么:



现在我应该在函数中做什么它可以使用多行文本框



代码借用但无法开始工作:



What I have tried:

now what should i Right in the function so it can work with a multi line text box

Code borrowed but can't get to work:

'' Duplicates the current line (or selection of lines) and places the copy
'' one line below or above the current cursor position (based upon the parameter)
Sub CopyLine(ByVal movingDown As Boolean)
    DTE.UndoContext.Open("CopyLine")
    Dim objSel As TextSelection = DTE.ActiveDocument.Selection

    ' store the original selection and cursor position
    Dim topPoint As TextPoint = objSel.TopPoint
    Dim bottomPoint As TextPoint = objSel.BottomPoint
    Dim lTopLine As Long = topPoint.Line
    Dim lTopColumn As Long = topPoint.LineCharOffset
    Dim lBottomLine As Long = bottomPoint.Line
    Dim lBottomColumn As Long = bottomPoint.LineCharOffset()

    ' copy each line from the top line to the bottom line
    Dim readLine As Long = lTopLine
    Dim endLine As Long = lBottomLine + 1
    Dim selectionPresent As Boolean = ((lTopLine <> lBottomLine) Or (lTopColumn <> lBottomColumn))
    If (selectionPresent And (lBottomColumn = 1)) Then
        ' A selection is present, but the cursor is in front of the first character
        ' on the bottom line. exclude that bottom line from the copy selection.
        endLine = lBottomLine
    End If

    ' figure out how many lines we are copying, so we can re-position
    ' our selection after the copy is done
    Dim verticalOffset As Integer = 0
    If (movingDown) Then
        verticalOffset = endLine - lTopLine
    End If

    ' copy each line, one at a time.
    ' The Insert command doesn't handle multiple lines well, and we need
    ' to use Insert to avoid autocompletions
    Dim insertLine As Long = endLine
    While (readLine < endLine)
        ' move to read postion, and read the current line
        objSel.MoveToLineAndOffset(readLine, 1)
        objSel.EndOfLine(True) 'extend to EOL
        Dim lineTxt As String = objSel.Text.Clone
        ' move to the destination position, and insert the copy
        objSel.MoveToLineAndOffset(insertLine, 1)
        objSel.Insert(lineTxt)
        objSel.NewLine()
        ' adjust the read & insertion points
        readLine = readLine + 1
        insertLine = insertLine + 1
    End While

    ' restore the cursor to original position and selection
    objSel.MoveToLineAndOffset(lBottomLine + verticalOffset, lBottomColumn)
    objSel.MoveToLineAndOffset(lTopLine + verticalOffset, lTopColumn, True)
    DTE.UndoContext.Close()
End Sub

'' Duplicates the current line (or selection of lines) and places the copy
'' one line below the current cursor position
Sub CopyLineDown()
    CopyLine(True)
End Sub

'' Duplicates the current line (or selection of lines) and places the copy
'' one line above the current cursor position
Sub CopyLineUp()
    CopyLine(False)
End Sub


'' Moves the selected lines up one line. If no line is
'' selected, the current line is moved.
''
Sub MoveLineUp()
    DTE.UndoContext.Open("MoveLineUp")
    Dim objSel As TextSelection = DTE.ActiveDocument.Selection
    ' store the original selection and cursor position
    Dim topPoint As TextPoint = objSel.TopPoint
    Dim bottomPoint As TextPoint = objSel.BottomPoint
    Dim lTopLine As Long = topPoint.Line
    Dim lTopColumn As Long = topPoint.LineCharOffset
    Dim lBottomLine As Long = bottomPoint.Line
    Dim lBottomColumn As Long = bottomPoint.LineCharOffset()

    Dim textLineAbove As TextSelection = DTE.ActiveDocument.Selection
    textLineAbove.MoveToLineAndOffset(lTopLine - 1, 1, False)
    textLineAbove.MoveToLineAndOffset(lTopLine, 1, True)
    Dim indentChange As Integer = CountIndentations(textLineAbove.Text) * -1

    ' If multiple lines are selected, but the bottom line doesn't
    ' have any characters selected, don't count it as selected
    Dim lEffectiveBottomLine = lBottomLine
    If ((lBottomColumn = 1) And (lBottomLine <> lTopLine)) Then
        lEffectiveBottomLine = lBottomLine - 1
    End If

    ' move to the line above the top line
    objSel.MoveToLineAndOffset(lTopLine - 1, 1)
    ' and move it down, until its below the bottom line:
    Do
        DTE.ExecuteCommand("Edit.LineTranspose")
    Loop Until (objSel.BottomPoint.Line >= lEffectiveBottomLine)
    ' Since the line we are on has moved up, our location in the file has changed:
    lTopLine = lTopLine - 1
    lBottomLine = lBottomLine - 1

    IndentBlockAndRestoreSelection(objSel, lBottomLine, lBottomColumn, lTopLine, lTopColumn, indentChange)

    DTE.UndoContext.Close()
End Sub

'' Moves the selected lines down one line. If no line is
'' selected, the current line is moved.
''
Sub MoveLineDown()
    DTE.UndoContext.Open("MoveLineDown")
    Dim objSel As TextSelection = DTE.ActiveDocument.Selection
    ' store the original selection and cursor position
    Dim topPoint As TextPoint = objSel.TopPoint
    Dim bottomPoint As TextPoint = objSel.BottomPoint
    Dim lTopLine As Long = topPoint.Line
    Dim lTopColumn As Long = topPoint.LineCharOffset
    Dim lBottomLine As Long = bottomPoint.Line
    Dim lBottomColumn As Long = bottomPoint.LineCharOffset()

    ' If multiple lines are selected, but the bottom line doesn't
    ' have any characters selected, don't count it as selected
    Dim lEffectiveBottomLine = lBottomLine
    If ((lBottomColumn = 1) And (lBottomLine <> lTopLine)) Then
        lEffectiveBottomLine = lBottomLine - 1
    End If

    Dim textLineBelow As TextSelection = DTE.ActiveDocument.Selection
    textLineBelow.MoveToLineAndOffset(lEffectiveBottomLine + 1, 1, False)
    textLineBelow.MoveToLineAndOffset(lEffectiveBottomLine + 2, 1, True)
    Dim indentChange As Integer = CountIndentations(textLineBelow.Text)


    ' move to the bottom line
    objSel.MoveToLineAndOffset(lEffectiveBottomLine, 1)
    ' and move it down, which effectively moves the line below it up
    ' then move the cursor up, always staying one line above the line
    ' that is moving up, and keep moving it up until its above the top line:
    Dim lineCount As Long = lEffectiveBottomLine - lTopLine
    Do
        DTE.ExecuteCommand("Edit.LineTranspose")
        objSel.LineUp(False, 2)
        lineCount = lineCount - 1
    Loop Until (lineCount < 0)
    ' Since the line we are on has moved down, our location in the file has changed:
    lTopLine = lTopLine + 1
    lBottomLine = lBottomLine + 1

    IndentBlockAndRestoreSelection(objSel, lBottomLine, lBottomColumn, lTopLine, lTopColumn, indentChange)

    DTE.UndoContext.Close()
End Sub

'' This method takes care of indenting the selected text by the indentChange parameter
'' It then restores the selection to the lTopLine:lTopColumn - lBottomLine:lBottomColumn parameter.
'' It will adjust these values according to the indentChange performed
Sub IndentBlockAndRestoreSelection(ByVal objSel As TextSelection, ByVal lBottomLine As Long, ByVal lBottomColumn As Long, ByVal lTopLine As Long, ByVal lTopColumn As Long, ByVal indentChange As Integer)
    ' restore the cursor to original position and selection
    objSel.MoveToLineAndOffset(lBottomLine, lBottomColumn)
    objSel.MoveToLineAndOffset(lTopLine, lTopColumn, True)
    If (indentChange = 0) Then
        ' If we don't change the indent, we are done
        Return
    End If

    If (lBottomLine = lTopLine) Then
        If (indentChange > 0) Then
            objSel.StartOfLine()
        Else
            objSel.StartOfLine()
            objSel.WordRight()
        End If
    End If
    objSel.Indent(indentChange)

    ' Since the selected text has changed column, adjust the columns accordingly:
    ' restore the cursor to original position and selection
    Dim lNewBottomColumn As Long = (lBottomColumn + indentChange)
    Dim lNewTopColumn As Long = (lTopColumn + indentChange)
    ' ensure that we we still on the page.
    ' The "or" clause makes it so if we were at the left edge of the line, we remain on the left edge.
    If ((lNewBottomColumn < 2) Or (lBottomColumn = 1)) Then
        ' Single line selections, or a bottomColumn that is already at 1 may still have a new BottomColumn of 1
        If ((lTopLine = lBottomLine) Or (lBottomColumn = 1)) Then
            lNewBottomColumn = 1
        Else
            ' If we have multiple lines selected, don't allow the bottom edge to touch the left column,
            ' or the next move will ignore that bottom line.
            lNewBottomColumn = 2
        End If
    End If
    If ((lNewTopColumn < 2) Or (lTopColumn = 1)) Then
        lNewTopColumn = 1
    End If

    ' restore the selection to the modified selection
    objSel.MoveToLineAndOffset(lBottomLine, lNewBottomColumn)
    objSel.MoveToLineAndOffset(lTopLine, lNewTopColumn, True)
End Sub


'' This method counts the indentation changes within the text provided as the paramter
Function CountIndentations(ByVal text As String) As Integer
    Dim indent As Integer = 0
    While (Text.Length > 0)
        If (Text.StartsWith("//")) Then
            Dim endOfLine As Integer = Text.IndexOf("\n", 2)
            If (Equals(endOfLine, -1)) Then
                ' The remaining text is all on one line, so the '//' terminates our search
                ' Ignore the rest of the text
                Exit While
            End If
            ' continue looking after the end of line
            Text = Text.Substring(endOfLine + 1)
        End If

        If (Text.StartsWith("/*")) Then
            Dim endComment As Integer = Text.IndexOf("*/", 2)
            If (Equals(endComment, -1)) Then
                ' This comment continues beyond the length of this line.
                ' Ignore the rest of the text
                Exit While
            End If
            ' continue looking after the end of this comment block
            Text = Text.Substring(endComment + 1)
        End If

        If (Text.StartsWith("{")) Then
            indent = indent + 1
        Else
            If (Text.StartsWith("}")) Then
                indent = indent - 1
            End If
        End If
        Text = Text.Substring(1)
    End While
    Return indent
End Function

推荐答案

我会帮你开始...



获取TextBox中插入符号的索引:
I'll get you started...

Get the index of the caret in the TextBox:
Dim caretIndex As Integer = textBox.SelectionStart

从插入符号索引中获取行号:

Get the line number from the caret index:

Dim lineNumber As Integer = textBox.GetLineFromCharIndex(caretIndex)

获取当前行中的字符索引:

Get the character index in the current line:

Dim characterXY As Point = textBox.GetPositionFromCharIndex(caretIndex)
Dim characterIndex As Integer = textBox.GetCharIndexFromPosition(characterXY)

其余的由您决定。



编辑:我会帮你找一个函数找到所有新行(或任何字符/文本)

The rest is up to you.

I'll help you a little with a function to find all the new lines (or any character/text)

Public Function AllIndexesOf(str As String, searchstring As String) As List(Of Integer)
    Dim index As Integer = str.IndexOf(searchstring)
    Dim indexes As List(Of Integer) = New List(Of Integer)()
    While index <> -1
        indexes.Add(index)
        index = str.IndexOf(searchstring, index + searchstring.Length)
    End While
    Return indexes
End Function

使用:

Dim text = "blah blah blah blah " + vbCrLf +
    "blah blah blah blah blah blah blah blah blah blah " + vbCrLf +
    "blah blah blah blah blah blah blah blah blah blah " + vbCrLf +
    "blah blah blah blah blah blah blah blah blah blah "
Dim indexes As List(Of Integer) = AllIndexesOf(text, vbCrLf)


Quote:

How to move a line up / down with alt + arrow_up and alt + arrow_down

How to move a line up / down with alt + arrow_up and alt + arrow_down



In a textbox, the sequence is select line, cut selection, move cursor, paste clipboard.



When you don’t understand what your code is doing or why it does what it does, the answer is debugger.

Use the debugger to see what your code is doing.只需设置断点并查看代码执行情况,调试器允许您逐行执行第1行并在执行时检查变量,这是一个令人难以置信的学习工具。



调试器 - 维基百科,免费的百科全书 [ ^ ]

掌握Visual Studio 2010中的调试 - 初学者指南 [ ^ ]



调试器在这里显示你的代码正在做什么,你的任务是与它应该做什么进行比较。

调试器中没有魔法,它没有发现错误,它只是帮助你。 When the code don’t do what is expected, you are close to a bug.


In a textbox, the sequence is select line, cut selection, move cursor, paste clipboard.

When you don't understand what your code is doing or why it does what it does, the answer is debugger.
Use the debugger to see what your code is doing. Just set a breakpoint and see your code performing, the debugger allow you to execute lines 1 by 1 and to inspect variables as it execute, it is an incredible learning tool.

Debugger - Wikipedia, the free encyclopedia[^]
Mastering Debugging in Visual Studio 2010 - A Beginner's Guide[^]

The debugger is here to show you what your code is doing and your task is to compare with what it should do.
There is no magic in the debugger, it don't find bugs, it just help you to. When the code don't do what is expected, you are close to a bug.


Because we are here to help ...



If I understood the requirement in the right way this TextBox would help :

Because we are here to help ...

If I understood the requirement in the right way this TextBox would help :
Public Class Edit_MLTextbox
    Inherits TextBox

    Sub New()
        MyBase.Multiline = True
    End Sub

    Protected Overrides Sub OnKeyDown(e As KeyEventArgs)
        Dim myKey As System.Windows.Forms.Keys = e.KeyCode
        Dim myAltPressed As Boolean = e.Alt
        Dim myLine As Integer = -1

        If myAltPressed AndAlso (Me.SelectionStart >= 0) Then
            myLine = Me.GetLineFromCharIndex(Me.SelectionStart)
            If myLine <> -1 Then
                If (myKey = Keys.Add) And (myLine < Me.Lines.Count - 1) Then
                    XChange(Me.Text, Me.Lines(myLine), Me.Lines(myLine + 1))
                    e.Handled = True
                ElseIf (myKey = Keys.Subtract) And (myLine > 0) Then
                    XChange(Me.Text, Me.Lines(myLine), Me.Lines(myLine - 1))
                    e.Handled = True
                End If
            End If
        End If

        MyBase.OnKeyDown(e)
    End Sub

    Private Sub XChange(ByRef sourceText As String, ByRef xchg1 As String, xchg2 As String)
        sourceText = sourceText.Replace(xchg1, Chr(1))
        sourceText = sourceText.Replace(xchg2, Chr(2))
        sourceText = sourceText.Replace(Chr(1), xchg2)
        sourceText = sourceText.Replace(Chr(2), xchg1)
    End Sub

End Class


这篇关于如何使用alt + arrow_up和alt + arrow_down向上/向下移动一条线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆