Подтвердить что ты не робот

Отображать полосу прокрутки в текстовом поле, когда содержимое выходит за рамки С#

Можно ли показать/скрыть полосу прокрутки в текстовом поле, только если количество строк в текстовом поле больше количества отображаемых строк?

4b9b3361

Ответ 1

Рассмотрите возможность использования RichTextBox - это встроенное поведение.

Ответ 2

Public Class TextBoxScrollbarPlugin
    Private WithEvents mTarget As TextBox

    ''' <summary>
    ''' After the Handle is created, mTarget.IsHandleCreated always returns
    ''' TRUE, even after HandleDestroyed is fired.
    ''' </summary>
    ''' <remarks></remarks>
    Private mIsHandleCreated As Boolean = False

    Public Sub New(item As TextBox)
        mTarget = item
        mIsHandleCreated = mTarget.IsHandleCreated
    End Sub

    Private Sub Update()
        If Not mTarget.IsHandleCreated Then
            Return
        ElseIf Not mIsHandleCreated Then
            Return
        End If
        Dim textBoxRect = TextRenderer.MeasureText(mTarget.Text,
                                                   mTarget.Font,
                                                   New Size(mTarget.Width, Integer.MaxValue),
                                                   TextFormatFlags.WordBreak + TextFormatFlags.TextBoxControl)

        Try
            If textBoxRect.Height > mTarget.Height Then
                mTarget.ScrollBars = ScrollBars.Vertical
            Else
                mTarget.ScrollBars = ScrollBars.None
            End If
        Catch ex As System.ComponentModel.Win32Exception
            'this sometimes throws a "failure to create window handle"
            'error.
            'This might happen if the TextBox is unvisible and/or
            'to small to display a toolbar.
            If mLog.IsWarnEnabled Then mLog.Warn("Update()", ex)
        End Try
    End Sub

    Private Sub mTarget_HandleCreated(sender As Object, e As System.EventArgs) Handles mTarget.HandleCreated
        mIsHandleCreated = True
    End Sub

    Private Sub mTarget_HandleDestroyed(sender As Object, e As System.EventArgs) Handles mTarget.HandleDestroyed
        mIsHandleCreated = False
    End Sub

    Private Sub mTarget_SizeChanged(sender As Object, e As System.EventArgs) Handles mTarget.SizeChanged
        Update()
    End Sub

    Private Sub mTarget_TextChanged(sender As Object, e As System.EventArgs) Handles mTarget.TextChanged
        Update()
    End Sub

End Class


Private mPlugins As New List(Of Object)
Private Sub Form_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    mPlugins.Add(New TextBoxScrollbarPlugin(txtBoxOne))
    mPlugins.Add(New TextBoxScrollbarPlugin(txtBoxTwo))
    mPlugins.Add(New TextBoxScrollbarPlugin(txtBoxThree))
End Sub  

Ответ 3

Спасибо, манекен, он работает! Здесь короткая версия фиктивного ответа в С#

Вызов этого кода в конце обработчиков SizeChanged и TextChanged:

Size textBoxRect = TextRenderer.MeasureText(
    this.YourTextBox.Text, 
    this.YourTextBox.Font, 
    new Size(this.YourTextBox.Width, int.MaxValue),
    TextFormatFlags.WordBreak | TextFormatFlags.TextBoxControl);
try
{
    this.YourTextBox.ScrollBars = textBoxRect.Height > this.YourTextBox.Height ? 
        ScrollBars.Vertical : 
        ScrollBars.None;
} catch (System.ComponentModel.Win32Exception)
{
     // this sometimes throws a "failure to create window handle" error.
     // This might happen if the TextBox is unvisible and/or
     // too small to display a toolbar.
}

Ответ 4

У меня есть решение tnimas, работающее в vb. Функции довольно хорошо написаны, и я не видел ошибок.

    Private Sub TextBoxSizeChanged(sender As Object, e As EventArgs) Handles Me.SizeChanged
    Dim textBoxRect As Size = TextRenderer.MeasureText(TextBox.Text, TextBox.Font, New Size(TextBox.Width, Integer.MaxValue), TextFormatFlags.WordBreak Or TextFormatFlags.TextBoxControl)
    Try
        TextBox.ScrollBar = If(textBoxRect.Height > TextBox.Height, ScrollBars.Vertical, ScrollBars.None)
    Catch ex As Exception
        'handle error
    End Try
End Sub

Ответ 5

При всем уважении к предыдущим решениям, которые предлагают изменить свойство TextBox.ScrollBars, чтобы при необходимости показывать/скрывать вертикальную полосу прокрутки. Этот подход вызывает нежелательное поведение при редактировании текста во время выполнения, например:

  • Каждый раз, когда вертикальная полоса прокрутки отображается/скрывается, текстовое поле прокручивается как до начала текста, так и до каретки.

  • Иногда весь текст будет выделен и выделен, чтобы вы могли представить, что произойдет, если вы продолжите печатать.

Поэтому я думаю, что TextBox.ScrollBars не следует менять. Вместо этого лучше использовать функцию ShowScrollBar API, чтобы заставить FORCE вертикальную полосу прокрутки отображать/скрывать.

Здесь и далее решение VB.Net:

API

Private Const SB_VERT As Integer = 1

<DllImport("user32")>
Private Shared Function ShowScrollBar(ByVal hWnd As IntPtr, ByVal wBar As Integer, ByVal bShow As Boolean) As Boolean
End Function

Добавьте обработчики для событий TextChanged и SizeChanged.

Private Sub OnTextChanged(sender As Object, e As EventArgs)
 UpdateScrollBars()
End Sub

Private Sub OnSizeChanged(sender As Object, e As EventArgs)
 UpdateScrollBars()
End Sub

Добавьте метод UpdateScrollBars:

Private Sub UpdateScrollBars()
  If MyTextBox.ScrollBars = ScrollBars.Vertical Then
     Dim sz As Size = TextRenderer.MeasureText(MyTextBox.Text, MyTextBox.Font, New Size(MyTextBox.Width, Integer.MaxValue), TextFormatFlags.WordBreak Or TextFormatFlags.TextBoxControl)
     Try
         Dim bShow As Boolean = (sz.Height + MyTextBox.Font.Height) > MyTextBox.Height
         ShowScrollBar(MyTextBox.Handle, SB_VERT, bShow)
     Catch
     End Try
  End If
End Sub

Вот и все.

С уважением.