开发者

Refer to an individual ListBoxItem

I have a Listbox displaying data, with a small border separating each item. The problem is that I only want a border between items, not at the top or bottom of the list. I figured that if I can retreive the first ListBoxItem in the list I can set it's border's thickness to 0.0, meaning that the borders only appear inbetween list items.

<ListBox Name="PerformanceList" ItemsSource="{Binding JFifoCollection}" HorizontalContentAlignment="Stretch">
                        <ListBox.ContextMenu>
                            <ContextMenu>
                                <MenuItem Name="ClearPerf" Click="MenuItem_Click" Header="Clear" />
                            </ContextMenu>
                        </ListBox.ContextMenu>
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <Border BorderThickness="0,1,0,0" BorderBrush="#ff000099">
                                    <Grid>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="100" />
                                            <ColumnDefinition Width="100" /&g开发者_Python百科t;
                                            <ColumnDefinition />
                                        </Grid.ColumnDefinitions>
                                        <Grid.RowDefinitions>
                                            <RowDefinition />
                                            <RowDefinition />
                                            <RowDefinition />
                                            <RowDefinition />
                                            <RowDefinition />
                                            <RowDefinition />
                                        </Grid.RowDefinitions>
                                        <TextBlock Text="{Binding Path=tid}" Grid.Column="0" Grid.RowSpan="6" FontSize="65pt" VerticalAlignment="Center" />
                                        <TextBlock Grid.Column="1" Grid.Row="0" FontWeight="Bold">hwcrc</TextBlock>
                                        <TextBlock Text="{Binding Path=HWCRC}" Grid.Column="2" Grid.Row="0" />
                                        <TextBlock Grid.Column="1" Grid.Row="1" FontWeight="Bold">frame count</TextBlock>
                                        <TextBlock Text="{Binding Path=Frames}" Grid.Column="2" Grid.Row="1" />
                                        <TextBlock Grid.Column="1" Grid.Row="2" FontWeight="Bold">fps</TextBlock>
                                        <TextBlock Text="{Binding Path=FPS}" Grid.Column="2" Grid.Row="2" />
                                        <TextBlock Grid.Column="1" Grid.Row="3" FontWeight="Bold">faults</TextBlock>
                                        <TextBlock Text="{Binding Path=Faults}" Grid.Column="2" Grid.Row="3" />
                                        <TextBlock Grid.Column="1" Grid.Row="4" FontWeight="Bold">info</TextBlock>
                                        <TextBlock Text="{Binding Path=Info}" Grid.Column="2" Grid.Row="4" />
                                        <TextBlock Grid.Column="1" Grid.Row="5" FontWeight="Bold">config</TextBlock>
                                        <TextBlock Text="{Binding Path=Config}" Grid.Column="2" Grid.Row="5" />
                                    </Grid>
                                </Border>
                                <DataTemplate.Triggers>
                                </DataTemplate.Triggers>
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                    </ListBox>

Is it possible to do this?


Two ways to do this:

One is to implement a boolean IsFirstItem property in the view model that's set to true when an item is the first item in whatever collection contains it. (This assumes that an item can only be contained by one collection, and that items have access to their containing collection, which are not always the case.) Then add a style to the Border:

<Style TargetType="Border">
   <Setter Property="BorderThickness" Value="0,1,0,0"/>
   <Style.Triggers>
      <DataTrigger Binding="{Binding IsFirstItem}" Value="True">
         <Setter Property="BorderThickness" Value="0"/>
      </DataTrigger>
   </Style.Triggers>
</Style>

Another is to create a placeholder object and add it to the end (or the beginning) of the collection. Then use template selection to render it with a different template from the normal items, e.g.:

<ListBox.Resources>
   <DataTemplate TargetType="{x:Type MyRealItem}">
      <!-- what most items should look like -->
   </DataTemplate>
   <DataTemplate TargetType="{x:Type MyPlaceholderItem}">
      <!-- what the placeholder item should look like -->
   </DataTemplate>
</ListBox.Resources>
<ListBox.ItemTemplate>
   <DataTemplate>
      <ContentPresenter Content="{Binding}"/>
   </DataTemplate>
</ListBox.ItemTemplate>

If it's at the end, for instance, you can then give the placeholder a negative top margin that's the same width as your border thickness - so basically you're drawing a rectangle of the background color on top of the bottom border of the last item in your list.


Subscribe to the loaded event handler on the ListBox and give a name to the border that you want to change. In the loaded event handler do the following:

        if (listbox.ItemContainerGenerator.Status == System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
        {
                ListBoxItem container = listView.ItemContainerGenerator.ContainerFromItem(listbox.Items[0]) as ListViewItem;
                Border border = container.Template.FindName("borderName",container) as Border;
                if (border != null)
                   border.BorderThickness = new Thickness();
         }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜