处理 WPF TabItems 的可见性属性

7
我一直在研究针对TabItemsVisibility.Collapsed。当Visibility设置为Collapsed时,TabItem标题会被隐藏,但内容仍然可见。
我也尝试了这里提到的方法,但没有成功。
有没有办法隐藏TabItems中的内容并选择可见的标签?

1
你不需要其中任何一个。在概念上,TabControl只是一个ObservableCollection<ViewModel>的图形表示,每个视图模型都由一个选项卡项表示,并且在给定时间只有1个SelectedItem - Federico Berasategui
2个回答

12
您不需要那些。从概念上讲,TabControl 只是 ObservableCollection<ViewModel> 的图形表示,其中每个视图模型都由一个选项卡项表示,在给定时间只有一个 SelectedItem
<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>

代码后台:

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},
                                  }
                          };
        }
    }

视图模型:

    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);
            }
        }
    }
}

然后,对于每个选项卡,只需继承TabViewModel(在每个选项卡内创建适当的逻辑),以及为这些派生类中的每一个提供一个适当的DataTemplateapp.xaml或其他地方。
每当您想要从视图中删除选项卡项时,不要操作视图,而是操作ViewModel。这是WPF的全部方法。它通过消除在代码中操作复杂对象(UI元素)的需要来简化一切。每当设置 TabbedViewModel.SelectedItem.IsVisible = false;时,请确保还执行以下操作: TabbedViewModel.SelectedItem = TabbedViewModel.Items.First(x => x.IsVisible && x.IsEnabled); 这将防止您选择了一个不可见的选项卡项。

谢谢。我会处理这个并更新。这段代码似乎是我正在寻找的。 - aioracle
2023年,这仍然是首选的设计模式吗? - Uri London
1
@UriLondon 是的。除了使用 Avalonia 代替 WPF 外,您还应该使用源生成的 INPC 属性,而不是手动实现 INPC 属性。 - Federico Berasategui

1
嗨,只需向TabControl添加和删除TabItems而不是设置可见性。使用可见性打开和关闭还有一个问题,当你滚动、最小化或调整TabControl大小时会出现异常,比如索引超出范围。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接