WPF XAML ListView - 让TextBlock文本换行

3
我有一个ListView,ListView.ItemTemplate像这样

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

这将以以下方式显示ListView项目:
----------------------------------
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
----------------------------------

以上,每个项目的文件位置都会被换行,如果它不能适应ListView的宽度。

更新: 更新的XAML

更新2: 将网格容器的列宽设置为硬编码值将强制换行(参见上面的注释行)。 但是,由于表格可调整大小,网格和ListView也可调整大小。因此,我不能硬编码宽度。 它需要根据表单的当前大小进行换行。


1
我无法理解您的要求。您是否想要文本换行?因为我测试了您的代码,发现文本被分成了更多的行,这与预期不符。 - Massimiliano Kraus
@MK87 我已更新了XAML,但在我的情况下它并不起作用。非常感谢。 - pixel
3个回答

8

HorizontalContentAlignement="Stretch"设置在ListView对象本身上,以告诉它在可用空间内水平拉伸其内容,并将HorizontalScrollBarVisiblilty设置为Disabled,以确保禁用水平滚动。

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

enter image description here


你太棒了!就像我读到的你的文章一样。这解决了问题。我只剩下一个问题,就像这里描述的那样:http://stackoverflow.com/questions/37465077/wpf-xaml-listview-with-scrollbars?noredirect=1#comment62429367_37465077。Rachel,你介意评论一下吗?非常感谢。 - pixel

1
如果您使用Grid并设置<ColumnDefinition Width="*">,则GridColumn会尽可能地扩大以填充所有可用空间。只有在此之后,才进行其他操作,如换行。
在这种情况下,GridColumn变得足够大,以容纳单行上的所有文本。这就是文本不换行的原因:它不需要换行!它有足够的空间可以保持在一行上!
解决方案:设置固定的列宽,如200、100或任何尝试较小的宽度,并查看结果。在某个点上,文本必须换行,具有足够窄的GridColumn
对于可变宽度的解决方案:
您必须将内部Grid(带有RowDefinitions)的Width绑定到外部Grid(带有ColumnDefinitions)的ActualWidth
创建一个像这样的转换器:
public class OuterGridToInnerGridWidthConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return ((double)value) / 2;
    }
}

在这个例子中,我假设内部的Grid的宽度是外部宽度的一半。如果您将Grid的列设置为Width="*",并且第二列具有固定宽度 - 例如 - 50,则转换器可以是:
public class OuterGridToInnerGridWidthConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return ((double)value) - 50;
    }
}

制作了这个,将此属性添加到内部的Grid中:
Width="{Binding ActualWidth,
  RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid}},
  Converter={StaticResource OuterGridToInnerGridWidthConverter}}"

最后,将ListViewHorizontalContentAlignment="Stretch"设置为“Stretch”。 当您缩小或放大窗口时,此操作都有效: TextBlock 可正确调整大小和换行。

你说得对。我已经更新了上面的XAML并添加了注释。但是,由于表单是可调整大小的,所有内容都会相应地进行调整,因此我无法硬编码宽度。这就是相对定位应该发挥作用的方式。所以,我不能使用硬编码宽度。非常感谢。 - pixel
1
如果您将 Width="*" 留空并调整窗口大小使其变小,会发生什么?文本是否在某个点处换行?还是内容保持不变(可能带有水平滚动条)? - Massimiliano Kraus
1
如果Width="*",则根本不会发生换行。水平滚动条将显示。 - pixel
非常感谢。Rachel的回答解决了问题,但MK87仍然非常感激。 - pixel
1
我看过她的解决方案,它更简单、更优雅 :) - Massimiliano Kraus

0

你能试着将第一行的RowDefinition设置为:

<RowDefinition Height="Auto"/>

替代

<RowDefinition Height="*"/>

?

如果没有成功,请尝试暂时移除


Style="{StaticResource MyFilePathTextLabel}" 

另外,您没有分享它的代码,所以我认为它可能会破坏包装。


抱歉,但那不起作用。尝试了两个建议,非常感谢。 - pixel

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