Programing

WPF TextBlock의 자동 세로 스크롤 막대?

lottogame 2020. 3. 9. 08:00
반응형

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>

이렇게하면 그리드를 사용하지 않는 경우와 같이 텍스트 블록의 텍스트가 오버플로되지 않고 텍스트 블록 아래의 요소와 겹치지 않습니다. 텍스트 블록이 이미 다른 요소와 그리드에 있었지만 다른 솔루션을 시도했을 때 나에게 일어났습니다. 텍스트 블록의 너비는 자동이어야하며 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


이 제안을 텍스트 블록에서 작동 시키려고했지만 작동하지 못했습니다. 나는 심지어 디자이너로부터 작업을 시도했습니다. (레이아웃에서 하단의 아래쪽 화살표 "V"를 클릭하여 목록을 펼치십시오.) scrollviewer를 VisibleAuto 로 설정하려고 시도 했지만 여전히 작동하지 않습니다.

나는 결국 읽기 전용 속성 집합을 사용 하여 TextBlock포기 하고 매력처럼 작동했습니다.TextBox


다른 사람이이 문제를 가지고 있지만 경우 그나마 알고 내 포장 TextBlockScrollViewer내 UI를 엉망 somewhow - 간단한 내가 대체 것을 알아 냈 해결 방법으로 TextBlocka로 TextBox이와 같은

<TextBox  Name="textBlock" SelectionBrush="Transparent" Cursor="Arrow" IsReadOnly="True" Text="My Text" VerticalScrollBarVisibility="Auto">

스크롤 막대가있는 TextBox것처럼 보이고 동작하는를 만듭니다 TextBlock(디자이너에서 모두 수행 할 수 있음).


이것은 그 질문에 대한 간단한 해결책입니다. 세로 스크롤은 텍스트가 넘칠 때만 활성화됩니다.

<TextBox Text="Try typing some text here " ScrollViewer.VerticalScrollBarVisibility="Auto" TextWrapping="WrapWithOverflow" />

참고 URL : https://stackoverflow.com/questions/1192335/automatic-vertical-scroll-bar-in-wpf-textblock

반응형