需要一个带有文本修剪和最大行数的WPF TextBlock或TextBox

4
我需要一个具有TextTrimming和MaxLines功能的TextBlock或TextBox。 TextBlock有TextTrimming属性,而TextBox有MaxLines属性,但两者都不支持同时使用。 这是一个更大的控件的一部分,允许用户输入笔记并在ListBox中显示它们(请参见:如果感兴趣,Grief with WPF UserControl with ListBox and TextBox Can't get textwrapping to work)。 基本上,对于已输入的笔记,我想将笔记限制为2行。 如果超过2行,则在其末尾显示省略号(...)以表示还有更多的笔记。 如果用户悬停在缩写的笔记上,则会看到整个笔记作为弹出窗口。*该控件将放置在主网格上,并且可以是不同的大小(或调整大小),因此2行文字量可能会发生变化。 也就是说,在某些情况下可以完全显示的笔记在其他情况下可能会被缩写。

尝试将MaxLines功能添加到TextBlock中是否更好,还是将TextTrimming添加到TextBox中? 我看到了一些与我需要做的事情非常接近的帖子。 这里有一个在编辑时将TextTrimming添加到TextBox中,但不清楚MaxLines是否仍然有效: TextBox TextTrimming。 我没有找到任何关于将MaxLines属性添加到TextBlock中的内容。 请注意,Windows手机的TextBlock似乎具有此功能。 也许我不是唯一需要这个的人 :)

我有点惊讶这不是“开箱即用”的。 这似乎是一个常见的问题。 顺便说一下,对于TextBox,TextBlock甚至标签或其他东西都没有偏好。 这些只是ListBox项目,不可编辑。

非常感谢任何想法或指针。

- Dave *如果你在想,“他可能会接下来问如何在用户悬停在缩写的笔记上时显示弹出窗口”,那么你是正确的!

以下是一种处理该问题的方法,基于此stackoverflow帖子:Scrollable TextBlock Sized EXACTLY 2 Lines High,请参见Joel B Fant的答案。 关键思想是另一个不可见的TextBlock(下面称为“限制器”)具有2行(或您想要的任何内容)。 然后,将文本块的高度属性绑定到虚拟“限制器”文本块的ActualHeight属性。 这是我的XAML样式,它似乎有效:

<UserControl x:Class="MyControlsLibrary.Views.NotesControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">

<UserControl.Resources>
    <DataTemplate x:Key="DefaultTemplate">
        <Grid x:Name="GridItem" >
            <Grid.ColumnDefinitions>
                <ColumnDefinition   />   

            </Grid.ColumnDefinitions>
            <ScrollViewer Margin="0,5,5,0" MaxHeight="{Binding ElementName=limiter,Path=ActualHeight}" HorizontalAlignment="Stretch" VerticalAlignment="Top" VerticalScrollBarVisibility="Hidden">
                <TextBlock   x:Name="NoteText" Grid.Column="0"  Height="{Binding ElementName=limiter,Path=ActualHeight}"  Text="{Binding Path=NoteText}"   TextTrimming="WordEllipsis" TextWrapping="Wrap">
                    <TextBlock.ToolTip>
                        <TextBlock Text="{Binding Path=NoteText}" TextWrapping="Wrap"></TextBlock>
                    </TextBlock.ToolTip>
            </TextBlock>
            </ScrollViewer>
            <TextBlock x:Name="limiter" Grid.Column="0"  Margin="0,5,5,0" Visibility="Hidden" HorizontalAlignment="Left" Width="10"  VerticalAlignment="Top">
            a <LineBreak/> b
            </TextBlock>

        </Grid>
    </DataTemplate>
</UserControl.Resources>
<Grid Name="LayoutRoot">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <TextBox TextWrapping="Wrap" Grid.Row="0"  Text="{Binding Path=NewNoteText, UpdateSourceTrigger=PropertyChanged}"   LostFocus="TextBox_LostFocus" AcceptsReturn="True">
        <TextBox.InputBindings>
            <KeyBinding Command="{Binding Path=AddNote}" Key="Enter"/>
        </TextBox.InputBindings>
    </TextBox>

    <ListBox     
        ScrollViewer.HorizontalScrollBarVisibility="Disabled"  Grid.Row="1"  ItemsSource="{Binding Path=Notes}"  Margin="5" ItemTemplate="{DynamicResource DefaultTemplate}"   SelectionChanged="NotesControl_SelectionChanged">
        </ListBox>


</Grid>

1个回答

6

您可以从默认的TextBlock中获得该功能。与使用MaxLines属性不同,您可以使用普通的Height属性。以下是一个非常简单的示例:

<TextBlock Text="This is some very important note which just happens to be quite long" 
    Height="38" Width="150" TextWrapping="Wrap" TextTrimming="CharacterEllipsis" />

输入图像描述

请注意,我在此处仅将Width设置为显示带有省略号的两行文本。在您的项目中,您应该让Grid设置它的Width

当然,您不能将其用于文本输入,因此如果您感兴趣,可以从Code Project上的WPF TextBox With Ellipsis页面下载带有省略号的TextBox


谢谢您快速的回应,Sheridan。我考虑使用Height属性(或MaxHeight),也许这是我要走的路,但是如果字体不是我所期望的那样,并且由于这是用户控件,我将不知道正在使用哪些字体,所以我认为可能会遇到一些问题。请参阅:https://dev59.com/fVfUa4cB1Zd3GeqPEhm4 - Dave
然后,您可以覆盖PropertyMetaData,为UserControl.FontProperty DependencyProperty添加一个PropertyChangedCallback处理程序,每次更改时都可以测量文本高度取决于新的FontFamily值。 - Sheridan
谢谢Sheridan。我采用了您在原回答中提到的“高度”想法,并加以运用,但我并没有完全按照您的建议去做。相反,我借鉴了Joel B Fant在https://dev59.com/fVfUa4cB1Zd3GeqPEhm4中的回答,他使用了一个“虚拟”文本块来设置高度。我在我的原始问题中添加了细节。我将您的答案标记为最佳答案,因为它给了我启发和解决问题的途径。非常感谢! - Dave

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接