문제

I need a TextBlock or TextBox that has TextTrimming and MaxLines. TextBlock has a TextTrimming property and TextBox has a MaxLines property but neither supports both. This is part of a larger control to allow the user to enter notes and display them in a ListBox ( see: Grief with WPF UserControl with ListBox and TextBox Can't get textwrapping to work if interested). Basically, for already entered notes, I'd like to limit the note to 2 lines. If it's longer than 2 lines, I'd show an ellipse (...) at the end of it to indicate there is more to the note. If the user hovers over an abbreviated note, he/she would see the entire note as a popup.* The control will be put on a main grid and could be different sizes (or resized) so the amount of text in 2 lines could change. I.e. a note that can be fully displayed in some situatiions might end up being abbreviated in other situations.

Would it be better to try to add the MaxLines functionality to TextBlock, or add the TextTrimming to TextBox? I have seen some posts that seem close to what I need to do. Here's one that adds TextTrimming to a TextBox but only when editing and it's not clear if the MaxLines still works: TextBox TextTrimming I didn't come across anything about adding the MaxLines property to TextBlock. Note that TextBlock for windows phones seems to have it. Perhaps I'm not the only one that needed this :)

I'm a little surprised this isn't available "right out of the box". It would seem to be a common problem. Incidentally, there's no preference as to TextBox, TextBlock, or even a Label or something else. These are just the ListBox items and are NOT editable.

Any ideas or pointers are much appreciated.

-Dave *If you're thinking, "he's probably going to next ask how to display a popup when the user hovers over the abbreviated note", you're quite correct!

Here is a way to handle the problem based on this stackoverflow post: Scrollable TextBlock Sized EXACTLY 2 Lines High See answer by Joel B Fant. The key idea is another invisible TextBlock (called "limiter" below) with 2 lines (or whatever you want). You then bind the Height property of your textblock to the ActualHeight of the dummy "limier" textblock. Here's what my XAML looks like and it appears to work:

<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>

도움이 되었습니까?

해결책

You can get that functionality from the default TextBlock. Instead of using the MaxLines property, you can just use the plain old Height property. Here's a very simple example:

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

enter image description here

Bear in mind that I've only set the Width here to show you the two lines of text shown with the character ellipsis. In your project, you should let a Grid set it's Width.

Of course you can't use this for text input, so if you're interested, you can download a TextBox with ellipsis from the WPF TextBox With Ellipsis page on Code Project.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top