Handling WPF TabItems Visibility property
Solution 1
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.
Solution 2
Hi just Add and Remove the TabItems from TabControl instead of setting Visibility. There is one more issue with Turning on and off the Visibility and it is exception like Out of index when you scroll or minimize or resize the TabControl.
Related videos on Youtube
aioracle
Updated on September 15, 2022Comments
-
aioracle over 1 year
I have been reading about
Visibility.Collapsed
forTabItems
. When theVisibility
is set toCollapsed
, theTabItem
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.-
Federico Berasategui about 11 yearsYou don't need any of that. Conceptually, a
TabControl
is just a graphical representation of anObservableCollection<ViewModel>
, where each viewmodel is represented by a tab item, and there's only 1SelectedItem
at a given time.
-