简体   繁体   中英

WPF XAML ListView - Make TextBlock Text wrap

I have a ListView with ListView.ItemTemplate like this

<ListView
    x:Name="myList" 
    BorderBrush="Transparent"
    ItemsSource="{Binding MyItems}" 
    SelectedIndex="0"
    ScrollViewer.CanContentScroll="True"
    ScrollViewer.VerticalScrollBarVisibility="Auto">

    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
            <Setter Property="Padding" Value="0" />
        </Style>
    </ListView.ItemContainerStyle>

    <ListView.ItemTemplate>
        <DataTemplate>
            <Grid Margin="5,5,5,5">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="200"/> <--THIS WILL FORCE WRAPPING
                    <ColumnDefinition Width="50"/>
                </Grid.ColumnDefinitions>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>

                    <TextBlock Text="{Binding FilePath}" 
                               Grid.Row="0" Margin="3,3,3,3" 
                               Style="{StaticResource MyFilePathTextLabel}" 
                               TextWrapping="WrapWithOverflow"/>   <-- THIS WILL NOT WRAP TEXT
                    <StackPanel Orientation="Horizontal" Grid.Row="1" Margin="3,3,3,3">
                        <TextBlock Text="Lab location: "/>
                        <TextBlock Text="{Binding LabLocation}" 
                                   Style="{StaticResource MyLabLocationTextLabel}"/>
                    </StackPanel>
                    ...
                    ...
        </DataTemplate>
    </ListView.ItemTemplate>
    ...
    ...
</ListView>

This will show ListView items like this:

----------------------------------
C:/samples/folderA/myfile1.txt     <-- NO WRAP AS IT FITS
Lab location: Chemistry Lab 301
----------------------------------
C:/samples/folderA/folderB/fold
erC/folderD/folderE/folderF/myf
ile2.txt                           <-- WRAP SINCE NOT FITTING
Lab location: Chemistry Lab 301
----------------------------------
C:/samples/folderA/folderB/myfi
le3.txt                            <-- WRAP SINCE NOT FITTING
Lab location: Chemistry Lab 301
----------------------------------
C:/samples/folderA/folderB/fold
erC/folderD/folderE/folderF/fol
derG/folderH/folderI/folderJ/fo
lderK/myfile4.txt                  <-- WRAP SINCE NOT FITTING
Lab location: Chemistry Lab 301
----------------------------------
C:/samples/myfile5.txt             <-- NO WRAP AS IT FITS
Lab location: Chemistry Lab 301
----------------------------------

Above, each item show file location as wrapped if it does not fit the width of the ListView.

UPDATE: Updated XAML

UPDATE 2: Setting the column Width of grid container to hardcoded value of will force wrapping (see above commented line). But since form is resizable, the grid and ListView is also resizable. Therefore, I can not hardcode width. It needs to wrap according to the current size of the form.

Set the HorizontalContentAlignement="Stretch" on the ListView object itself to tell it to stretch it's Content horizontally to fit available space, and set the HorizontalScrollBarVisiblilty to Disabled to make sure horizontal scrolling is disabled.

<ListView x:Name="myList" ...
          HorizontalContentAlignment="Stretch"
          ScrollViewer.HorizontalScrollBarVisibility="Disabled">

在此处输入图片说明

If you use a Grid and set <ColumnDefinition Width="*"> , the GridColumn enlarges as much as possible to fill all the available space. Only and only after that, other operations like wrapping take place.

In this case, the GridColumn becomes large enough to contain all the text on a single line. And that's the reason why the text doesn't wrap: it doesn't need to wrap! It has all the space it needs to stay on a single line!

SOLUTION: Set a fixed column width, as 200, or 100, or anyway try a smaller width, and see the result. At some point the text MUST wrap, with a GridColumn thin enough.

SOLUTION FOR FLEXIBLE WIDTH:

You have to bind the Width of the inner Grid (the one with the RowDefinitions ) to the ActualWidth of the outer Grid (the one with the ColumnDefinitions ).

Create a converter like this:

public class OuterGridToInnerGridWidthConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return ((double)value) / 2;
    }
}

In this example I suppose that the inner Grid has half the Width of the outer. If instead you have the column of the Grid with Width="*" and the second column with a fixed width of - for example - 50 , the converter can be:

public class OuterGridToInnerGridWidthConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return ((double)value) - 50;
    }
}

Made this, add this attribute to the inner Grid :

Width="{Binding ActualWidth,
  RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid}},
  Converter={StaticResource OuterGridToInnerGridWidthConverter}}"

Finally, set HorizontalContentAlignment="Stretch" for the ListView .

This works both when you make the window smaller or bigger: the TextBlock resizes and wraps correctly.

Can you try to have the first RowDefinition like :

<RowDefinition Height="Auto"/>

instead of

<RowDefinition Height="*"/>

?

If no success, try temporarily removing the

Style="{StaticResource MyFilePathTextLabel}" 

also. You did not share its code, so I'm thinking it might break the wrapping.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM