WPF XAML ListView - 使 TextBlock 文本换行
WPF XAML ListView - Make TextBlock Text wrap
我有一个 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 也是可调整大小的。因此,我不能硬编码宽度。 需要根据当前窗体大小换行
您能否尝试让第一个 RowDefinition 像:
<RowDefinition Height="Auto"/>
而不是
<RowDefinition Height="*"/>
?
如果不成功,请尝试暂时删除
Style="{StaticResource MyFilePathTextLabel}"
还有。你没有分享它的代码,所以我认为它可能会破坏包装。
如果使用Grid
并设置<ColumnDefinition Width="*">
,则GridColumn
会尽可能放大以填满所有可用的space。仅且仅在 之后,其他操作(如包装)才会发生。
在这种情况下,GridColumn
变得足够大,可以在一行中包含所有文本。这就是文本不换行的原因:它不需要换行!它具有保持在一条线上所需的所有 space!
解决方案:设置一个固定的列宽,如 200 或 100,或者尝试更小的宽度,然后查看结果。在某些时候,文本必须换行,GridColumn
足够细。
灵活宽度的解决方案:
您必须将内部 Grid
的 Width
(带有 RowDefinitions
的那个)绑定到外部 Grid
的 ActualWidth
(带有 ColumnDefinitions
).
的那个
像这样创建一个转换器:
public class OuterGridToInnerGridWidthConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((double)value) / 2;
}
}
在这个例子中,我假设内部 Grid
是外部 Width
的一半。相反,如果 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}}"
最后,为ListView
设置HorizontalContentAlignment="Stretch"
。
这在您将 window 变小或变大时都有效:TextBlock
会正确调整大小和换行。
在 ListView 对象本身上设置 HorizontalContentAlignement="Stretch"
以告诉它水平拉伸其内容以适应可用 space,并将 HorizontalScrollBarVisiblilty
设置为禁用以确保水平滚动是已禁用。
<ListView x:Name="myList" ...
HorizontalContentAlignment="Stretch"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
我有一个 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 也是可调整大小的。因此,我不能硬编码宽度。 需要根据当前窗体大小换行
您能否尝试让第一个 RowDefinition 像:
<RowDefinition Height="Auto"/>
而不是
<RowDefinition Height="*"/>
?
如果不成功,请尝试暂时删除
Style="{StaticResource MyFilePathTextLabel}"
还有。你没有分享它的代码,所以我认为它可能会破坏包装。
如果使用Grid
并设置<ColumnDefinition Width="*">
,则GridColumn
会尽可能放大以填满所有可用的space。仅且仅在 之后,其他操作(如包装)才会发生。
在这种情况下,GridColumn
变得足够大,可以在一行中包含所有文本。这就是文本不换行的原因:它不需要换行!它具有保持在一条线上所需的所有 space!
解决方案:设置一个固定的列宽,如 200 或 100,或者尝试更小的宽度,然后查看结果。在某些时候,文本必须换行,GridColumn
足够细。
灵活宽度的解决方案:
您必须将内部 Grid
的 Width
(带有 RowDefinitions
的那个)绑定到外部 Grid
的 ActualWidth
(带有 ColumnDefinitions
).
像这样创建一个转换器:
public class OuterGridToInnerGridWidthConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((double)value) / 2;
}
}
在这个例子中,我假设内部 Grid
是外部 Width
的一半。相反,如果 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}}"
最后,为ListView
设置HorizontalContentAlignment="Stretch"
。
这在您将 window 变小或变大时都有效:TextBlock
会正确调整大小和换行。
在 ListView 对象本身上设置 HorizontalContentAlignement="Stretch"
以告诉它水平拉伸其内容以适应可用 space,并将 HorizontalScrollBarVisiblilty
设置为禁用以确保水平滚动是已禁用。
<ListView x:Name="myList" ...
HorizontalContentAlignment="Stretch"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">