#wpf #xaml
#wpf #xaml
Вопрос:
В следующем XAML я пытаюсь обернуть текстовый блок, который привязывается к «PortfolioCodes» и «CommentaryText», но, похоже, что «Перенос» не работает для TextBlock. Я перепробовал все возможные предложения, которые смог найти на этом веб-сайте, но все напрасно. Может кто-нибудь, пожалуйста, помочь.
<Grid>
<ListBox ItemsSource="{Binding Path=Summaries}" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemTemplate>
<DataTemplate>
<Border CornerRadius="5" BorderBrush="LightGray" BorderThickness="1" Padding="4" Margin="4">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="15"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0">No Of Security</TextBlock>
<TextBlock Grid.Column="2" Grid.Row="0" Text="{Binding Path=PortfolioSecurityCount}"></TextBlock>
<TextBlock Grid.Column="0" Grid.Row="1">Portfolio Code(s)</TextBlock>
<Grid Grid.Column="2" Grid.Row="1" >
<TextBlock TextWrapping="Wrap" Text="{Binding Path=PortfolioCodes}"></TextBlock>
</Grid>
<TextBlock Grid.Column="0" Grid.Row="2">Commentary Text</TextBlock>
<Grid Grid.Column="2" Grid.Row="2" >
<TextBlock Grid.Column="2" Grid.Row="2" TextWrapping="Wrap" Text="{Binding Path=CommentaryText}"></TextBlock>
</Grid>
</Grid>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Основываясь на ответе Guge, я изменил xaml, как показано ниже, и теперь он работает.
<Grid x:Name="LayoutRoot">
<ListBox x:Name="SummaryListBox" ItemsSource="{Binding Path=Summaries}" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemTemplate>
<DataTemplate>
<Border CornerRadius="5" BorderBrush="LightGray" BorderThickness="1" Padding="4" Margin="4">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="15"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0">No Of Security</TextBlock>
<TextBlock Grid.Column="2" Grid.Row="0" Text="{Binding Path=PortfolioSecurityCount}"></TextBlock>
<TextBlock Grid.Column="0" Grid.Row="1">Portfolio Code(s)</TextBlock>
<TextBlock Grid.Column="2" Grid.Row="1" TextWrapping="Wrap" Text="{Binding Path=PortfolioCodes}" ></TextBlock>
<TextBlock Grid.Column="0" Grid.Row="2">Commentary Text</TextBlock>
<TextBlock Grid.Column="2" Grid.Row="2" TextWrapping="Wrap" Text="{Binding Path=CommentaryText}"></TextBlock>
</Grid>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Ответ №1:
Измените ширину вашего третьего определения столбца с «Auto» на «*», таким образом, оно займет только то, что осталось от вашего горизонтального пространства.
Чтобы попытаться объяснить это: область экрана в WPF распределяется по двухпроходному алгоритму. Сначала каждый визуальный элемент запрашивает у каждого дочернего элемента, сколько ему нужно места, с указанием того, сколько его доступно. Эти дочерние элементы делают то же самое для своих дочерних элементов. Затем каждый визуальный элемент сообщает каждому дочернему элементу, сколько они на самом деле получат. Эти дочерние элементы, опять же, делают то же самое для своих дочерних элементов.
Вашему коду не удалось выполнить то, что вы хотели, потому что сетка в DataTemplate сообщила своим дочерним элементам третьего столбца, что они могут иметь все горизонтальное пространство, которое они хотели («auto») при первом запуске. Затем эти текстовые поля подумали, что их не нужно переносить. Поэтому они просто сообщили о своей желаемой ширине и высоте в одну строку. Во втором запуске Grid обнаружил, что значение «auto» оказалось немного меньше того, что хотели эти дочерние элементы. И сетка по-прежнему давала им высоту всего в одну строку, поэтому о переносе не могло быть и речи. После этого у дочерних элементов не осталось другого выбора, кроме как обрезать текст.
Когда ширина третьего столбца установлена на «*», сетка сообщит дочерним элементам в этом столбце, сколько именно горизонтальных пикселей осталось после того, как первый столбец получил значение «auto», а второй столбец — 15. Теперь текстовые поля могут понять, что они могут захотеть перенести, и они сообщают в ответ: «Хорошо, папа, я обойдусь этими жалкими горизонтальными пикселями, но, по крайней мере, дай мне то, что я хочу в вертикалях». Вертикальное пространство не ограничено, поэтому они получают то, что им нужно, чтобы представить весь свой великолепный контент.
Комментарии:
1. Выдающееся объяснение того, что происходит под капотом WPF! 1 кажется недостаточным.
2. Спасибо Guge, это сработало и очень хорошее объяснение на деле. Теперь я всегда буду помнить об этом.
Ответ №2:
Попробуйте предоставить width
вашему TextBlock
, по умолчанию TextBlock
занимает все доступное пространство и не переносит текст