在WPF TextBlock的自动垂直滚动条?(Automatic vertical scroll

2019-06-27 00:10发布

我有一个TextBlock WPF中。 我写了许多行了,这远超过其垂直高度。 我希望这种情况发生时,垂直滚动条自动出现,但事实并非如此。 我试图寻找在属性面板中的滚动条属性,但没能找到。

我怎样才能让垂直滚动条为我自动创建TextBlock一旦其内容超出它的高度?

澄清:我宁愿做它从设计,而不是通过直接写入XAML。

Answer 1:

它包装在一个滚动浏览器:

<ScrollViewer>
    <TextBlock />
</ScrollViewer>

注:此答案适用于TextBlock在原来的问题问(只读文本元素)。

如果你想显示在滚动条TextBox (可编辑的文本元素),然后使用ScrollViewer附加属性:

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

对于这两个属性的有效值是DisabledAutoHiddenVisible



Answer 2:

现在可以使用以下命令:

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


Answer 3:

更好的东西是:

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

这可以确保在你的文本块中的文本不溢出,重叠的文本块下面的元件可能是这种情况,如果你不使用网格。 这发生在我身上时,我试过其他的解决方案,即使正文块已经在与其他元素的网格。 请记住,该文本块的宽度应为汽车,应指定在Grid元素所需。 我这样做在我的代码,它精美的作品。 HTH。



Answer 4:

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

这是一种使用滚动文本框在XAML和使用它作为一个文本区域。



Answer 5:

这个答案描述了使用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,您可以将所有的具体记录代码到它自己的视图模型的:

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
}

下面是它如何工作的:

  • 该视图模型切换的附加属性来控制文本框。
  • 因为它是使用“附加”,这是快如闪电。
  • 任何其他视图模型可以通过调用日志视图模型方法生成的日志信息。
  • 当我们使用内置的文本框的ScrollViewer中,我们可以每次增加新的消息时,它会自动滚动到文本框的底部。


Answer 6:

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

我通过把MaxHeight在ScrollViewer中以另一种方式这样做。

只需调整MaxHeight显示文本的更多或更少的线。 简单。



Answer 7:

您可以使用

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

这些附加WPF的财产。 欲获得更多信息

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



Answer 8:

我试图让这些建议的文本块的工作,但不能让它开始工作。 我甚至试图把它从设计工作。 (看看布局,并通过点击向下箭头“V”的底部展开列表)我试过的ScrollViewer设置为可见 ,然后自动 ,但它仍然是行不通的。

我最终放弃了,改变了TextBlockTextBox只读属性集,和它的工作就像一个魅力。



Answer 9:

不知道如果别人有这个问题,但我的包装TextBlockScrollViewer somewhow搞砸了我的用户界面-作为一个简单的解决方法我想通了,更换TextBlock一个TextBox像这样的

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

创建一个TextBox的外观和行为像一个TextBlock有一个滚动条(你可以做到这一切的设计师)。



Answer 10:

这是一个简单的解决这个问题。 只有当文本溢出的垂直滚动将被激活。

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



文章来源: Automatic vertical scroll bar in WPF TextBlock?