Silverlight 3: ListBox DataTemplate HorizontalAlignment

做~自己de王妃 提交于 2019-11-27 20:04:23
markti

When creating Data Templates for ListBox, you should not incldue <ListBoxItem>. The contents of the DataTemplate will be placed inside of a generated container. You can control how that container is constructed using ItemContainerStyle.

The default control style for ListBoxItem is used to define the ItemContainerStyle by default. This style sets the ListBoxItem.HorizontalContentAlignment property to 'Left'. Notice how the ContentPresenter binds its HorizontalAlignment to this property.

You need to override the style of the ListBoxItem container that is being generated when you bind to your ListBox. This can be done by setting the ItemContainerStyle. Set the HorizontalContentAlignment property to be "Stretch".

Below is the default ListBoxItem Style. Included for reference.

<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>

I spent an hour trying to resolve this one. Very very frustrasting. You don't have to override the entire default style for the ListBoxItem. I couldn't get this to work. In the end I resolved the issue by simply overriding just the HorizontalContentAlignment property in my ListBox.ItemContainerStyle section e.g:

            <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>

This worked a treat for me.

Myles

Here is an example of using the control templates and data templates for the listbox control. Refer to the XAML markup which streaches the border for the listbox items.

My ListBoxItem contained a CheckBox and the above solutions did not work for me (most likely due to the nature of a CheckBox, not those solutions) I was able to coerce this functionality by not binding to the "Content" property of the checkbox, but explicitely defining the XAML inline:

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

The margin is needed because the TextBox text did not align with the CheckBox's checkmark. The MinWidth was also necessary.

I am working with Silverlight 5 with VS 2012. I have the same issue. I have horizontal listbox with my own custom objects as ItemsSource. I want listbox items to expand. But they are not expanding. I donot want to give any hard coded width for every listbox item. I tried all answers here but nothing works. I just gave ItemsSource ={Binding Persons} DisplayMemberPath="First Name". Thats all

Two things I noticed here, because I had the same issue and wasn't able to solve it the way you're trying.

First, you don't need to explicitly put a ListBoxItem in your DataTemplate. This is created for you automatically, so you actually have your ListBoxItem inside of the one that was created for you. I checked this out in Snoop to confirm.

Second, and I don't know exactly why, but I wasn't able to get the stretching behavior out of the alignment attributes either. I changed it to use RelativeSource binding on the Width attribute to the ActualWidth property of the containing ListBoxItem. This worked for me.

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

If you need to set style properties on the ListBoxItem that is implicitly created for you, use a Style element inside of the ListBox.ItemContainerStyle element.

Hope this helps...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!