Search
Write a publication
Pull to refresh

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

Задача состояла в разработке небольшого 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. Я остановился на первом варианте. Все прекрасно работает.

Удачной вам разработки!
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.