23
votes

I have a listbox where the itemtemplate is using a style. The styles specifies a border with a datatrigger setting the visibility of the border to collapsed depending on a property. This works fine except I can still see a very narrow line for each item, in the list, that is collapsed. I was hoping someone could help with how to set the visibility so that there are no visible traces as this is quite apparent when consecutive items have been collapsed.

The datatemplate specifies an outer border with a dockpanel inside of this - there are then stackpanels docked to this.

Any help is appreciated.

Well this is a simplified template:

<DataTemplate x:Key="myTemplate">
    <Border BorderThickness="0">
        <Border.Style>
            <Style>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Path=IsActive}" Value="False">
                        <Setter Property="Border.Visibility" Value="Collapsed" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Border.Style>
        <DockPanel LastChildFill="True" HorizontalAlignment="Stretch">
            <StackPanel DockPanel.Dock="Right" HorizontalAlignment="Right"  >
                <TextBlock Text="{Binding Path=SeqNo, Converter={StaticResource SeqToTextConv}}"/>
                <Label Content="..." />
            </StackPanel>
        </DockPanel>
    </Border>
</DataTemplate>
3
can you post some example XAML that illustrates the problem?BrokenGlass
adding it to the original postc95mbq

3 Answers

42
votes

You are succesfully hiding your item, however, the ListBox wraps each of your items within a ListBoxItem, this adds concepts such as selection to your item. I suspect you are still seeing the ListBoxItem in the case where your items are hidden. You can use the ItemContainerStyle to hide ListBoxItems ...

<ListBox>
  <ListBox.ItemContainerStyle>
    <Style TargetType="{x:Type ListBoxItem}">
      <Style.Triggers>
        <DataTrigger Binding="{Binding IsActive}" Value="False">
          <Setter Property="Visibility" Value="Collapsed"/>
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </ListBox.ItemContainerStyle>
</ListBox>
1
votes

This can also be achieved by populating ListBox.Items only with ListBoxItem instead of other controls:

ListBox.Items.Add(new ListBoxItem { 
    Content = new CheckBox {Content = "item 1"} 
    })

or

<ListBox>
    <ListBox.Items>
        <ListBoxItem>
            <CheckBox Content="item 1"/>
        </ListBoxItem>
    </ListBox.Items>
</ListBox>

Then in the code behind or in the trigger, you can hide the items directly:

ListBox.Items[0].Visibility = Visibility.Collapse

This will hide the item as well as the 4px border. This method gives you control of visibility for each individual item.

0
votes

I went with ColinE's proposed solution. Here is a full snipped for everybody's convenience. Thanks ColienE.

      <ListBox ItemsSource="{Binding Properties}" Height="110">
            <ListBox.ItemTemplate>
                <HierarchicalDataTemplate>
                    <CheckBox Content="{Binding Name}" IsChecked="{Binding IsSelected}" Visibility="{Binding Visible}" />
                </HierarchicalDataTemplate>
            </ListBox.ItemTemplate>
            <ListBox.ItemContainerStyle>
                <Style TargetType="{x:Type ListBoxItem}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Visible}" Value="Collapsed">
                            <Setter Property="Visibility" Value="Collapsed"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ListBox.ItemContainerStyle>
      </ListBox>