I'm using Visual Studio 2015 and MVVM Light Toolkit to build a WPF app. When the user clicks an employee in a DataGrid, we show the record's details to allow editing. This details area consists of two tabs: Demographics and Tests. The Tests tab displays a ListView of the tests for this person.
Here's the structure:
MainWindow.xaml:
<DataTemplate x:Key="EmployeeSearchTemplate">
    <view:EmployeeSearchView />
</DataTemplate>
<ContentControl ContentTemplate="{StaticResource EmployeeSearchTemplate}" />
EmployeeSearchView.xaml:
<UserControl.DataContext>
    <viewModel:EmployeeSearchViewModel />
</UserControl.DataContext>
<ContentControl Content="{Binding SelectedEmployee}"
                ContentTemplate="{StaticResource EmployeeViewTemplate}" .../>
When the user selects the Tests tab, we search the db and return the tests for this employee, if any.
EmployeeView.xaml:
<DataTemplate x:Key="TestsViewTemplate">
    <views:TestsView />
</DataTemplate>
<TabControl SelectedIndex="{Binding SelectedTabIndex}">
    <TabItem>
        <!-- Demographic details of record here -->
    </TabItem>
    <TabItem>
        <!-- Employee test info here. When user selects this tab, search db 
             and return tests for this employee, if any -->
        <ContentControl Content="{Binding TestsVm}"
                        ContentTemplate="{StaticResource TestsViewTemplate}" /> 
    </TabItem>
</TabControl>   
Here are the constructor and some properties for EmployeeViewModel.cs:
private TestsViewModel _testsVm;
private int _selectedTabIndex;
public EmployeeViewModel ()
{
    // Other initialization code...
    _selectedTabIndex = 0;
    this.PropertyChanged += (o, e) =>
    {
        if (e.PropertyName == nameof(SelectedTabIndex))
        {
            // If tab 1 selected, the person is on the Tests tab
            // Perform search and populate the TestsVM object's Tests
            // by executing the RelayCommand on it
            if (SelectedTabIndex.Equals(1))
            {
                TestsVm = new TestsViewModel
                {
                    SelectedEmployeeId = EmployeeId
                };
                TestsVm.SearchTestsRelayCommand.Execute(null);
            }
        }
    };
} 
public TestsViewModel TestsVm
{
    get { return _testsVm; }
    set
    {
        if (Equals(value, _testsVm)) return;
        _testsVm = value;
        RaisePropertyChanged();
    }
}
public int SelectedTabIndex
{
    get { return _selectedTabIndex; }
    set
    {
        if (value == _selectedTabIndex) return;
        _selectedTabIndex = value;
        RaisePropertyChanged();
    }
}   
Here's the ListView in TestsView.xaml:
<ListView ItemsSource="{Binding Tests}"
          Visibility="{Binding HasTests,
                               Converter={helpers:BooleanToVisibilityConverter WhenTrue=Visible,
                                                                               WhenFalse=Hidden}}">
    <ListView.View>
        <GridView>
            <!-- GridView columns here -->
        </GridView>
    </ListView.View>
</ListView>
Here's code from TestsViewModel.cs:
private ObservableCollection<TestViewModel> _tests;
private int _selectedEmployeeId;
private bool _hasTests;
public TestsViewModel()
{
    SearchTestsRelayCommand = new RelayCommand(CallSearchTestsAsync);
    this.PropertyChanged += (o, e) =>
    {
        if (e.PropertyName == nameof(Tests))
        {
            HasTests = !Tests.Count.Equals(0);
        }
    };
}  
public RelayCommand SearchTestsRelayCommand { get; private set; }
private async void CallSearchTestsAsync()
{
    await SearchTestsAsync(SelectedEmployeeId);
}
private async Task SearchTestsAsync(int employeeId)
{
    ITestDataService dataService = new TestDataService();
    try
    {
        Tests = await dataService.SearchTestsAsync(employeeId);
    }
    finally
    {
        HasTests = !Tests.Count.Equals(0);
    }
}   
public ObservableCollection<TestViewModel> Tests
{
    get { return _tests; }
    set
    {
        if (Equals(value, _tests)) return;
        _tests = value;
        RaisePropertyChanged();
    }
}
public bool HasTests
{
    get { return _hasTests; }
    set
    {
        if (value == _hasTests) return;
        _hasTests = value;
        RaisePropertyChanged();
    }
}
public int SelectedEmployeeId
{
    get { return _selectedEmployeeId; }
    set
    {
        if (value == _selectedEmployeeId) return;
        _selectedEmployeeId = value;
        RaisePropertyChanged();
    }
}
The HasTests property is not changing and thus not hiding the ListView when it's empty. Note that I also tried the following for the ListView visibility, pointing to its own HasItems to no avail:
Visibility="{Binding HasItems,
   RelativeSource={RelativeSource Self},
   Converter={helpers:BooleanToVisibilityConverter WhenTrue=Visible,
                                                   WhenFalse=Hidden}}"  
I've used the same BooleanToVisibilityConverter successfully elsewhere, so it's something with my code. I'm open to your suggestions. Thank you. 
Update: Here's the XAML for TestView.xaml:
<UserControl x:Class="DrugComp.Views.TestsView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:helpers="clr-namespace:DrugComp.Helpers"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:sys="clr-namespace:System;assembly=mscorlib"
             xmlns:viewModel="clr-namespace:DrugComp.ViewModel"
             xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
             d:DesignHeight="300"
             d:DesignWidth="300"
             mc:Ignorable="d">
    <UserControl.Resources />
    <Grid Width="Auto"
          Height="700"
          Margin="5,7,5,5"
          HorizontalAlignment="Left">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="32" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="32" />
            <RowDefinition Height="32" />
            <RowDefinition Height="32" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0"
                   Grid.ColumnSpan="2"
                   HorizontalAlignment="Left"
                   Style="{StaticResource Instruction}"
                   Text="{Binding Instructions}" />
        <ListView Grid.Row="1"
                  Grid.ColumnSpan="2"
                  Width="Auto"
                  Margin="5"
                  HorizontalAlignment="Center"
                  VerticalAlignment="Top"
                  AlternationCount="2"
                  ItemContainerStyle="{DynamicResource CustomListViewItemStyle}"
                  ItemsSource="{Binding Tests}"
                  SelectedItem="{Binding SelectedTest}">
            <ListView.Style>
                <Style TargetType="{x:Type ListView}">
                    <Setter Property="Visibility" Value="Visible" />
                    <Style.Triggers>
                        <Trigger Property="HasItems" Value="False">
                            <!-- If you want to save the place in the layout, use 
                Hidden instead of Collapsed -->
                            <Setter Property="Visibility" Value="Collapsed" />
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </ListView.Style>
            <ListView.View>
                <GridView>
                    <GridViewColumn Width="50"
                                    DisplayMemberBinding="{Binding TestId}"
                                    Header="Test ID" />
                    <GridViewColumn Width="90"
                                    DisplayMemberBinding="{Binding EmployeeId}"
                                    Header="Employee ID" />
                    <GridViewColumn Width="90"
                                    DisplayMemberBinding="{Binding OrderedDate,
                                                                   StringFormat='MM/dd/yyyy'}"
                                    Header="Ordered Date" />
                    <GridViewColumn Width="119"
                                    DisplayMemberBinding="{Binding ValidReasonForTest.Description}"
                                    Header="Reason" />
                    <GridViewColumn Width="129"
                                    DisplayMemberBinding="{Binding OrderedByWhom}"
                                    Header="Ordered By" />
                    <GridViewColumn Width="90"
                                    DisplayMemberBinding="{Binding ScheduledDate,
                                                                   StringFormat='MM/dd/yyyy'}"
                                    Header="Scheduled Date" />
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</UserControl>
 
     
    