Silverlight 3: ListBox DataTemplate HorizontalAlignment

У меня есть ListBox, с которым ItemTemplate привязан к DataTemplate. Моя проблема в том, что я не могу заставить элементы в шаблоне растягиваться до полной ширины ListBox.

<ListBox x:Name="listPeople" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" 
    Margin="0,0,0,0" Background="{x:Null}" SelectionMode="Extended" Grid.Row="1" 
    ItemTemplate="{StaticResource PersonViewModel.BrowserDataTemplate}" 
    ItemsSource="{Binding Mode=OneWay, Path=SearchResults}" >
</ListBox>

<DataTemplate x:Key="PersonViewModel.BrowserDataTemplate">
   <ListBoxItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
     <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="5,5,5,5">
       <Border Opacity=".1" x:Name="itemBorder"  Background="#FF000000"   
         HorizontalAlignment="Stretch" VerticalAlignment="Stretch" 
         CornerRadius="5,5,5,5" MinWidth="100" Height="50"/>
      </Grid>
   </ListBoxItem>
</DataTemplate>

Как вы можете видеть, я добавил границу внутри сетки, чтобы указать ширину шаблона. Моя цель - увидеть, что эта граница расширяется до полной ширины списка. В настоящее время его ширина определяется его содержимым или MinWidth, что является единственной вещью, которая в настоящий момент сохраняет ее видимой.

Ответ 1

При создании шаблонов данных для ListBox вы не должны включать <ListBoxItem>. Содержимое DataTemplate будет помещено внутри созданного контейнера. Вы можете контролировать, как этот контейнер строится с помощью ItemContainerStyle.

Стиль управления по умолчанию для ListBoxItem используется для определения ItemContainerStyle по умолчанию. Этот стиль устанавливает для свойства ListBoxItem.HorizontalContentAlignment значение "Left". Обратите внимание, как ContentPresenter привязывает его HorizontalAlignment к этому свойству.

Вам необходимо переопределить стиль контейнера ListBoxItem, который создается при привязке к вашему ListBox. Это можно сделать, установив ItemContainerStyle. Установите для свойства HorizontalContentAlignment значение "Stretch".

Ниже приведен стиль ListBoxItem по умолчанию. Включено для справки.

<Style x:Key="ListBoxItemStyle1" TargetType="ListBoxItem">
            <Setter Property="Padding" Value="3"/>
            <Setter Property="HorizontalContentAlignment" Value="Left"/>
            <Setter Property="VerticalContentAlignment" Value="Top"/>
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="TabNavigation" Value="Local"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <Grid Background="{TemplateBinding Background}">
                            <!-- VSM excluded for readability -->
                            <Rectangle x:Name="fillColor" Fill="#FFBADDE9" RadiusX="1" RadiusY="1" IsHitTestVisible="False" Opacity="0"/>
                            <Rectangle x:Name="fillColor2" Fill="#FFBADDE9" RadiusX="1" RadiusY="1" IsHitTestVisible="False" Opacity="0"/>
                            <ContentPresenter x:Name="contentPresenter" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>
                            <Rectangle x:Name="FocusVisualElement" Stroke="#FF6DBDD1" StrokeThickness="1" RadiusX="1" RadiusY="1" Visibility="Collapsed"/>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

Ответ 2

Я потратил час, пытаясь решить эту проблему. Очень очень неприятно. Вам не приходится переопределять весь стиль по умолчанию для ListBoxItem. Я не мог заставить это работать. В конце концов я решил проблему, просто переопределив только свойство HorizontalContentAlignment в разделе ListBox.ItemContainerStyle, например:

            <ListBox x:Name="ClassList" ItemsSource="{Binding LineClasses}"
                     ScrollViewer.VerticalScrollBarVisibility="Visible"
                     SelectionMode="Extended"
                     ScrollViewer.HorizontalScrollBarVisibility="Hidden" HorizontalContentAlignment="Stretch"
                     HorizontalAlignment="Stretch" Loaded="ClassList_Loaded"
                     VerticalAlignment="Stretch" Grid.Row="0">
                <ListBox.ItemContainerStyle>
                    <Style TargetType="ListBoxItem">
                        <Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
                    </Style>
                </ListBox.ItemContainerStyle>
                    <ListBox.ItemTemplate>

                    <DataTemplate>
                        <Border BorderBrush="Black" CornerRadius="3" Background="#FFE88D34"
                            BorderThickness="1" HorizontalAlignment="Stretch" >
                            <Grid Background="Transparent" HorizontalAlignment="Stretch" >
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*" />
                                </Grid.ColumnDefinitions>
                                <TextBlock 
                                    Grid.Column="0" HorizontalAlignment="Stretch"
                                    Margin="2"                                   
                                    FontSize="10"
                                    Text="{Binding DisplayClassNm}"/>
                            </Grid>

                        </Border>
                    </DataTemplate>
                </ListBox.ItemTemplate>

Это сработало для меня.

Майлс

Ответ 3

Здесь приведен пример использования шаблонов управления и шаблонов данных для элемента управления списком. Обратитесь к разметке XAML, которая перемещает границу для элементов списка.

Ответ 4

В My ListBoxItem содержался CheckBox, и вышеупомянутые решения не работали для меня (скорее всего, из-за особенностей CheckBox, а не для тех решений) я смог принудить эту функциональность, не привязавшись к свойству "Содержимое" checkbox, но явно определяя встроенную строку XAML:

<CheckBox HorizontalAlignment="Stretch" IsChecked="{Binding Path=IsSelected, Mode=TwoWay}">
    <TextBlock
        MinWidth="130"
        Margin="0,-2,0,0"
        HorizontalAlignment="Stretch"
        Text="{Binding Path=DisplayText}" />
</CheckBox>

Значение поля необходимо, поскольку текст TextBox не совпадает с флажком CheckBox. Также необходим MinWidth.

Ответ 5

Я работаю с Silverlight 5 с VS 2012. У меня такая же проблема. У меня есть горизонтальный список с моими собственными пользовательскими объектами как ItemsSource. Я хочу, чтобы элементы списка расширялись. Но они не расширяются. Я не хочу давать строчную кодированную ширину для каждого элемента списка. Я пробовал все ответы здесь, но ничего не работает. Я просто дал ItemsSource = {Binding Persons} DisplayMemberPath = "Имя". Thats all

Ответ 6

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

Во-первых, вам не нужно явно помещать ListBoxItem в свой DataTemplate. Это создано для вас автоматически, так что вы действительно имеете свой ListBoxItem внутри того, который был создан для вас. Я проверил это в Snoop для подтверждения.

Во-вторых, и я точно не знаю, почему, но я также не смог получить растягивающее поведение из атрибутов выравнивания. Я изменил его, чтобы использовать привязку RelativeSource для атрибута Width к свойству ActualWidth содержащего ListBoxItem. Это сработало для меня.

Width="{Binding RelativeSource={RelativeSource 
   AncestorType={x:Type ListBoxItem}}, Path=ActualWidth}"

Если вам нужно установить свойства стиля в элементе ListBoxItem, который неявно создан для вас, используйте элемент Style внутри элемента ListBox.ItemContainerStyle.

Надеюсь, что это поможет...