Тонкости работы ListBox в Silverlight

16 Мар
2012

Задача состояла в разработке небольшого Silverlight приложения, отображающего определенный контент. Логика работы в данном случае не имеет значения, так как проблемы проявились с разметкой.

Разметка:



xmlns:c="clr-namespace:SAC_Test"

* This source code was highlighted with Source Code Highlighter.


<UserControl.Resources>
<c:TestData x:Key="testData" x:Name="testData"/>
</UserControl.Resources>


* This source code was highlighted with Source Code Highlighter.


<Style TargetType="ListBox" >
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<TextBox TextWrapping="Wrap" Text="{Binding}"> </TextBox>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>


* This source code was highlighted with Source Code Highlighter.


<Grid Name="grdMap" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<sdk:GridSplitter Grid.Column="1"
HorizontalAlignment="Center"
VerticalContentAlignment="Stretch"
Width="3"/>
<Grid Name="grdIncidents" Grid.Column="0">
<ListBox x:Name="lsbIncidents" ItemsSource="{StaticResource testData}">
</ListBox>
</Grid>
</Grid>


* This source code was highlighted with Source Code Highlighter.



Класс TestData:

 namespace SAC_Test
{
public class TestData : List
{
public TestData()
{
Add("aaaaaaaaaaaa aaaaaaaaa aaaaaaaaaa aaaaaaaaaaaa aaaaaaaaaaaa aaaaaaaaaaa");
Add("aaaaaaaaaaaa aaaaaaaaa aaaaaaaaaa aaaaaaaaaaaa aaaaaaaaaaaa aaaaaaaaaaa");
Add("aaaaaaaaaaaa aaaaaaaaa aaaaaaaaaa aaaaaaaaaaaa aaaaaaaaaaaa aaaaaaaaaaa");
}
}
}


* This source code was highlighted with Source Code Highlighter.


Казалось бы, все просто и предсказуемо, за исключением одного НО! TextBox не изменяет своего размера при перемещении GridSplitter’а и текст внутри него не переносится по словам:
Текст не переносится по словам

После долгих и упорных, местами откровенно шаманских, попыток добится предсказуемого отображения элементов ListBox’а, появился следующий код, который решал проблему:
Изменения коснулись стиля элемента ListBox:

<Style TargetType="ListBox" >
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<TextBox TextWrapping="Wrap" Text="{Binding}"> </TextBox>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
</ControlTemplate>
</Setter.Value>
</Setter>

</Style>


* This source code was highlighted with Source Code Highlighter.



Соответственно, результат:

Теперь текст отображается корректно

Но как-то это, согласитесь, странно: задали пустой шаблон для всего элемента управления — и поведение стало предсказуемым.
Решил разобраться в этом подробнее. В MSDN была найдена разметка, реализующая шаблон по-умолчанию для ListBox:msdn.microsoft.com

Вот часть разметки с MSDN, в которой кроется разгадка:


<ScrollViewer x:Name="ScrollViewer" 
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
BorderBrush="Transparent"
BorderThickness="0"
TabNavigation="{TemplateBinding TabNavigation}">
<ItemsPresenter />
</ScrollViewer>


* This source code was highlighted with Source Code Highlighter.



Разработчики обернули ItemsPresenter ScrollViewer’ом. У ScrollViewer’a свойство HorizontalScrollBarVisibility имеет значение «auto», и, как следствие, вместо переноса текста просто появляется полоска прокрутки.
Решение:

Решений может быть несколько.
Во-первых, можно оставить тот вариант, который был предложен выше, где к стилю ListBox’a добавляется пустой ControlTemplate.
Ну и во-вторых, можно взять шаблон из MSDN и дополнить стиль ScrollViewer’a:

<UserControl.Resources>
...
<Style TargetType="ScrollViewer">
<Setter Property="HorizontalScrollBarVisibility" Value="Disabled"/>
</Style>
...
</UserControl.Resources>


* This source code was highlighted with Source Code Highlighter.



Но второй вариант будет работать, только если полностью переопределить стиль ListBox (или скопировать XAML разметку с MSDN).
Если в дальнейшем потребуется горизонтальная полоса прокрутки, то просто в нужном месте локально задаем этому свойству значение. Локальное значение имеет больший приоритет, так что проблем не возникнет.

P.S. Я остановился на первом варианте. Все прекрасно работает.

Удачной вам разработки!
По материалам Хабрахабр.



загрузка...

Комментарии:

Наверх