[C#] WPF TextBlock의 자동 세로 스크롤 막대?

나는이 TextBlockWPF에. 수직 높이를 훨씬 초과하여 많은 행을 씁니다. 그런 일이 발생하면 세로 스크롤 막대가 자동으로 나타날 것으로 예상했지만 그렇지 않았습니다. 속성 창에서 스크롤 막대 속성을 찾으려고했지만 찾을 수 없습니다.

TextBlock내용물이 높이를 초과 하면 세로 스크롤 막대가 자동으로 만들어 지려면 어떻게해야합니까?

설명 : 나는 XAML에 직접 쓰는 것이 아니라 디자이너로부터 그것을하고 싶습니다.



답변

스크롤 뷰어로 감싸십시오.

<ScrollViewer>
    <TextBlock />
</ScrollViewer>

참고이 답변 TextBlock은 원래 질문에서 요구 한대로 (읽기 전용 텍스트 요소)에 적용됩니다 .

TextBox(편집 가능한 텍스트 요소) 에 스크롤 막대를 표시 하려면 ScrollViewer연결된 속성 을 사용하십시오 .

<TextBox ScrollViewer.HorizontalScrollBarVisibility="Disabled"
         ScrollViewer.VerticalScrollBarVisibility="Auto" />

이 두 가지 속성에 대한 유효한 값은 Disabled, Auto, HiddenVisible.


답변

지금 다음을 사용할 수 있습니다 :

<TextBox Name="myTextBox"
         ScrollViewer.HorizontalScrollBarVisibility="Auto"
         ScrollViewer.VerticalScrollBarVisibility="Auto"
         ScrollViewer.CanContentScroll="True">SOME TEXT
</TextBox>


답변

더 나은 것 :

<Grid Width="Your-specified-value" >
    <ScrollViewer>
         <TextBlock Width="Auto" TextWrapping="Wrap" />
    </ScrollViewer>
</Grid>

이렇게하면 그리드를 사용하지 않는 경우와 같이 텍스트 블록의 텍스트가 오버플로되지 않고 텍스트 블록 아래의 요소와 겹치지 않습니다. 텍스트 블록이 이미 다른 요소와 그리드에 있었지만 다른 솔루션을 시도했을 때 나에게 일어났습니다. 텍스트 블록의 너비는 자동이어야하며 그리드 요소에서 원하는 것을 지정해야합니다. 내 코드 에서이 작업을 수행했으며 아름답게 작동합니다. HTH.


답변

<ScrollViewer Height="239" VerticalScrollBarVisibility="Auto">
    <TextBox AcceptsReturn="True" TextWrapping="Wrap" LineHeight="10" />
</ScrollViewer>

XAML에서 스크롤하는 TextBox를 사용하여 텍스트 영역으로 사용하는 방법입니다.


답변

이 답변은 MVVM을 사용하는 솔루션을 설명합니다.

이 솔루션은 새 로깅 메시지가 추가 될 때마다 자동으로 맨 아래로 스크롤되는 로깅 상자를 창에 추가하려는 경우 유용합니다.

이러한 부착 된 속성이 추가되면 어디서나 재사용 할 수 있으므로 매우 모듈 식이며 재사용 가능한 소프트웨어가됩니다.

이 XAML을 추가하십시오.

<TextBox IsReadOnly="True"
         Foreground="Gainsboro"
         FontSize="13"
         ScrollViewer.HorizontalScrollBarVisibility="Auto"
         ScrollViewer.VerticalScrollBarVisibility="Auto"
         ScrollViewer.CanContentScroll="True"
         attachedBehaviors:TextBoxApppendBehaviors.AppendText="{Binding LogBoxViewModel.AttachedPropertyAppend}"
         attachedBehaviors:TextBoxClearBehavior.TextBoxClear="{Binding LogBoxViewModel.AttachedPropertyClear}"
         TextWrapping="Wrap">

첨부 된 속성을 추가하십시오.

public static class TextBoxApppendBehaviors
{
    #region AppendText Attached Property
    public static readonly DependencyProperty AppendTextProperty =
        DependencyProperty.RegisterAttached(
            "AppendText",
            typeof (string),
            typeof (TextBoxApppendBehaviors),
            new UIPropertyMetadata(null, OnAppendTextChanged));

    public static string GetAppendText(TextBox textBox)
    {
        return (string)textBox.GetValue(AppendTextProperty);
    }

    public static void SetAppendText(
        TextBox textBox,
        string value)
    {
        textBox.SetValue(AppendTextProperty, value);
    }

    private static void OnAppendTextChanged(
        DependencyObject d,
        DependencyPropertyChangedEventArgs args)
    {
        if (args.NewValue == null)
        {
            return;
        }

        string toAppend = args.NewValue.ToString();

        if (toAppend == "")
        {
            return;
        }

        TextBox textBox = d as TextBox;
        textBox?.AppendText(toAppend);
        textBox?.ScrollToEnd();
    }
    #endregion
}

그리고이 첨부 된 속성 (상자를 지우려면) :

public static class TextBoxClearBehavior
{
    public static readonly DependencyProperty TextBoxClearProperty =
        DependencyProperty.RegisterAttached(
            "TextBoxClear",
            typeof(bool),
            typeof(TextBoxClearBehavior),
            new UIPropertyMetadata(false, OnTextBoxClearPropertyChanged));

    public static bool GetTextBoxClear(DependencyObject obj)
    {
        return (bool)obj.GetValue(TextBoxClearProperty);
    }

    public static void SetTextBoxClear(DependencyObject obj, bool value)
    {
        obj.SetValue(TextBoxClearProperty, value);
    }

    private static void OnTextBoxClearPropertyChanged(
        DependencyObject d,
        DependencyPropertyChangedEventArgs args)
    {
        if ((bool)args.NewValue == false)
        {
            return;
        }

        var textBox = (TextBox)d;
        textBox?.Clear();
    }
}   

그런 다음 MEF와 같은 종속성 주입 프레임 워크를 사용하는 경우 모든 로깅 관련 코드를 자체 ViewModel에 배치 할 수 있습니다.

public interface ILogBoxViewModel
{
    void CmdAppend(string toAppend);
    void CmdClear();

    bool AttachedPropertyClear { get; set; }

    string AttachedPropertyAppend { get; set; }
}

[Export(typeof(ILogBoxViewModel))]
public class LogBoxViewModel : ILogBoxViewModel, INotifyPropertyChanged
{
    private readonly ILog _log = LogManager.GetLogger<LogBoxViewModel>();

    private bool _attachedPropertyClear;
    private string _attachedPropertyAppend;

    public void CmdAppend(string toAppend)
    {
        string toLog = $"{DateTime.Now:HH:mm:ss} - {toAppend}\n";

        // Attached properties only fire on a change. This means it will still work if we publish the same message twice.
        AttachedPropertyAppend = "";
        AttachedPropertyAppend = toLog;

        _log.Info($"Appended to log box: {toAppend}.");
    }

    public void CmdClear()
    {
        AttachedPropertyClear = false;
        AttachedPropertyClear = true;

        _log.Info($"Cleared the GUI log box.");
    }

    public bool AttachedPropertyClear
    {
        get { return _attachedPropertyClear; }
        set { _attachedPropertyClear = value; OnPropertyChanged(); }
    }

    public string AttachedPropertyAppend
    {
        get { return _attachedPropertyAppend; }
        set { _attachedPropertyAppend = value; OnPropertyChanged(); }
    }

    #region INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion
}

작동 방식은 다음과 같습니다.

  • ViewModel은 연결된 속성을 토글하여 TextBox를 제어합니다.
  • “Append”를 사용함에 따라 번개가 빠릅니다.
  • 다른 ViewModel은 로깅 ViewModel에서 메소드를 호출하여 로깅 메시지를 생성 할 수 있습니다.
  • TextBox에 내장 된 ScrollViewer를 사용하면 새 메시지가 추가 될 때마다 텍스트 상자의 맨 아래로 자동 스크롤되도록 할 수 있습니다.

답변

<ScrollViewer MaxHeight="50"
              Width="Auto"
              HorizontalScrollBarVisibility="Disabled"
              VerticalScrollBarVisibility="Auto">
     <TextBlock Text="{Binding Path=}"
                Style="{StaticResource TextStyle_Data}"
                TextWrapping="Wrap" />
</ScrollViewer>

MaxHeight를 ScrollViewer에 넣어 다른 방법 으로이 작업을 수행하고 있습니다.

텍스트 줄을 더 많거나 적게 표시하려면 MaxHeight를 조정하십시오. 쉬운.


답변

당신이 사용할 수있는

ScrollViewer.HorizontalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollBarVisibility="Visible"

이들은 wpf의 속성입니다. 자세한 내용은

http://wpfbugs.blogspot.in/2014/02/wpf-layout-controls-scrollviewer.html