Заставить TextBlock обернуть в WPF ListBox

94

У меня есть список WPF, в котором отображаются сообщения. Он содержит аватар слева, а имя пользователя и сообщение расположены вертикально справа от аватара. Макет хорош до тех пор, пока текст сообщения не будет переноситься по словам, но вместо этого я получаю горизонтальную полосу прокрутки в списке.

Я погуглил и нашел решения аналогичных проблем, но ни одно из них не помогло.

<ListBox HorizontalContentAlignment="Stretch"  ItemsSource="{Binding Path=FriendsTimeline}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <Border BorderBrush="DarkBlue" BorderThickness="3" CornerRadius="2" Margin="3" >
                    <Image Height="32" Width="32"  Source="{Binding Path=User.ProfileImageUrl}"/>
                </Border>
                <StackPanel Orientation="Vertical">
                    <TextBlock Text="{Binding Path=User.UserName}"/>
                    <TextBlock Text="{Binding Path=Text}" TextWrapping="WrapWithOverflow"/> <!-- This is the textblock I'm having issues with. -->
                </StackPanel>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
Эрик Хаскинс
источник

Ответы:

132

Содержимое TextBlockможно обернуть с помощью свойства TextWrapping. Вместо StackPanelиспользования DockPanel/ Grid. Еще один момент - установите для ScrollViewer.HorizontalScrollBarVisibilityсвойства Disabledзначение ListBox.

Обновлено Hiddenна Disabledоснове комментария Мэтта. Спасибо, Мэтт.

Нэш
источник
38
Я думаю, вам нужно установить ScrollViewer.HorizontalScrollBarVisibility на «Disabled», а не на «Hidden» - иначе ListBox все равно будет пытаться прокручивать по горизонтали, вы просто не увидите полосу прокрутки.
Мэтт Хэмилтон,
9

Проблема может быть не в ListBox. TextBlock не будет переноситься, если один из родительских элементов управления предоставляет достаточно места, поэтому нет необходимости в переносе. Это может быть вызвано элементом управления ScrollViewer.

Мартин Мозер
источник
1
Спасибо! в моем случае отключение горизонтальной прокрутки в списке устранило проблему ScrollViewer.HorizontalScrollBarVisibility = "Disabled"
Ateik
2

Если вы хотите, чтобы TextBlock не увеличивался, и вы хотите, чтобы он просто соответствовал размеру списка, вы должны явно указать его ширину.

Чтобы изменить его динамически, это означает не значение исправления, но вам необходимо привязать его к соответствующему родительскому элементу в визуальном дереве. У вас может получиться что-то вроде этого:

<ListBox ItemsSource="{Binding MyItems}" Name="MyListBox">

  <ListBox.Resources>
    <Style TargetType="ListBoxItem">
      <Setter Property="Width" 
              Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ScrollContentPresenter}, Path=ActualWidth}" />
    </Style>
  </ListBox.Resources>

  <ListBox.ItemTemplate>
    <DataTemplate>
      <TextBlock Text="{Binding Title}" TextWrapping="Wrap" />
    </DataTemplate>
  </ListBox.ItemTemplate>

</ListBox>

Если это не сработает, попробуйте найти нужные элементы (которые должны быть привязаны к чему) с помощью Live Visual Tree в Visual Studio.

Элдор
источник