source

WPF 텍스트 블록의 자동 수직 스크롤 막대?

factcode 2023. 6. 3. 08:45
반응형

WPF 텍스트 블록의 자동 수직 스크롤 막대?

나는 있습니다TextBlock입니다.는 수직 높이를 초과하여 .저는 세로 높이를 훨씬 넘는 많은 줄을 그 위에 씁니다.세로 스크롤 막대가 자동으로 나타날 것으로 예상했는데 나타나지 않았습니다.속성 창에서 스크롤 막대 속성을 찾아보았지만 찾을 수 없습니다.

수직 스크롤 막대를 자동으로 만드는 방법은 무엇입니까?TextBlock일단 내용물이 높이를 초과하면?

명확화:XAML에 직접 편지를 쓰는 것이 아니라 디자이너에게 부탁하고 싶습니다.

스크롤 뷰어로 래핑합니다.

<ScrollViewer>
    <TextBlock />
</ScrollViewer>

참고 이 답변은 다음에 적용됩니다.TextBlock(읽기 전용 텍스트 요소)를 입력합니다.

를 스롤막표시면으로 TextBox 가능한 요소)를합니다.ScrollViewer연결된 속성:

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

두은 " " " " 입니다.Disabled,Auto,Hidden그리고.Visible.

이제 다음을 사용할 수 있습니다.

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

ScrollViewer에 MaxHeight를 입력하여 다른 방법으로 작업을 수행하고 있습니다.

텍스트의 줄 수를 늘리거나 줄이려면 최대 높이를 조정하십시오.만만하다.

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

이것은 XAML에서 스크롤링 텍스트 상자를 텍스트 영역으로 사용하는 방법입니다.

제 ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅠTextBlock의 상태가.ScrollViewer으로 만든 - 으로 UI를 하는 것을 되었습니다.TextBlocka에 의하여TextBox이것처럼 말이다.

<TextBox  SelectionBrush="Transparent" 
          Cursor="Arrow" 
          IsReadOnly="True" 
          Text="{Binding Text}" 
          VerticalScrollBarVisibility="Auto">

를 생성합니다.TextBox겉모습과 행동이 마치TextBlock스크롤 막대를 사용하여 모든 작업을 디자이너에서 수행할 수 있습니다.

사용할 수 있습니다.

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

이것들은 wpf의 연결된 속성입니다.자세한 정보는

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

이 답변은 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은 로깅 ViewModel에서 메서드를 호출하여 로깅 메시지를 생성할 수 있습니다.
  • 텍스트 상자에 내장된 ScrollViewer를 사용하면 새 메시지가 추가될 때마다 텍스트 상자 아래쪽으로 자동으로 스크롤할 수 있습니다.

이러한 제안을 텍스트 블록에 적용하려고 했지만 실행할 수 없었습니다.저는 심지어 디자이너로부터 그것을 작동시키기 위해 노력했습니다. (레이아웃을 보고 아래의 아래쪽 화살표 "V"를 클릭하여 목록을 확장합니다.) 스크롤 뷰어를 Visible로 설정다음 Auto로 설정했지만 여전히 작동하지 않았습니다.

저는 결국 포기하고 그것을 바꿨습니다.TextBlock아주TextBox읽기 전용 속성이 설정되어 있고 매력적으로 작동했습니다.

이것은 그 질문에 대한 간단한 해결책입니다.수직 스크롤은 텍스트가 오버플로될 때만 활성화됩니다.

<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

반응형