I have been reading about Visibility.Collapsed
for TabItems
. When the Visibility
is set to Collapsed
, the TabItem
header is hidden but the contents are still visible.
I have also tried the following approch mentioned in here, but no luck.
Is there any way to get the contents inside the TabItems
to hide and also select the tab that is visible.
You don't need any of that. Conceptually, a TabControl
is just a graphical representation of an ObservableCollection<ViewModel>
, where each viewmodel is represented by a tab item, and there's only 1 SelectedItem
at a given time:
<Window x:Class="WpfApplication4.Window12"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window12" Height="300" Width="300">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
</Window.Resources>
<TabControl ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}">
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="IsEnabled" Value="{Binding IsEnabled}"/>
<Setter Property="Visibility" Value="{Binding IsVisible, Converter={StaticResource BoolToVisibilityConverter}}"/>
<Setter Property="Header" Value="{Binding Title}"/>
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
</Window>
Code Behind:
using System.Windows;
using BaseFramework.MVVM;
using System.Collections.ObjectModel;
namespace WpfApplication4
{
public partial class Window12 : Window
{
public Window12()
{
InitializeComponent();
DataContext = new TabbedViewModel()
{
Items =
{
new TabViewModel() {Title = "Tab #1", IsEnabled = true, IsVisible = true},
new TabViewModel() {Title = "Tab #2", IsEnabled = false, IsVisible = true},
new TabViewModel() {Title = "Tab #3", IsEnabled = true, IsVisible = false},
}
};
}
}
ViewModel:
public class TabbedViewModel: ViewModelBase
{
private ObservableCollection<TabViewModel> _items;
public ObservableCollection<TabViewModel> Items
{
get { return _items ?? (_items = new ObservableCollection<TabViewModel>()); }
}
private ViewModelBase _selectedItem;
public ViewModelBase SelectedItem
{
get { return _selectedItem; }
set
{
_selectedItem = value;
NotifyPropertyChange(() => SelectedItem);
}
}
}
public class TabViewModel: ViewModelBase
{
private string _title;
public string Title
{
get { return _title; }
set
{
_title = value;
NotifyPropertyChange(() => Title);
}
}
private bool _isEnabled;
public bool IsEnabled
{
get { return _isEnabled; }
set
{
_isEnabled = value;
NotifyPropertyChange(() => IsEnabled);
}
}
private bool _isVisible;
public bool IsVisible
{
get { return _isVisible; }
set
{
_isVisible = value;
NotifyPropertyChange(() => IsVisible);
}
}
}
}
Then, its just a matter of inheriting TabViewModel
for each one of your tabs (creating the appropiate logic inside of each), and a proper DataTemplate
for each one of these derived classes in the app.xaml
or something.
Whenever you want to remove a tab item from the view, instead of manipulating the view you manipulate the ViewModel. this is the WPF approach for everything. It simplifies everything by removing the need to manipulate complex objects (UI elements) in code. Whenever you set
TabbedViewModel.SelectedItem.IsVisible = false;
, make sure you also do:
TabbedViewModel.SelectedItem = TabbedViewModel.Items.First(x => x.IsVisible && x.IsEnabled);
This will prevent you from ever falling into the case of having an invisible tab item as the selected item.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With