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.
Надеюсь, что это поможет...