【问题标题】:How to hide tab control when item source list is empty项目源列表为空时如何隐藏选项卡控件
【发布时间】:2019-12-08 08:40:15
【问题描述】:

我有一个 WPF .NET Core 应用程序,其 TabControl 绑定到 TabItems 的 ObservableCollection。我希望在 ObservableCollection 变空时隐藏 TabControl,并且我想在其位置显示另一个面板。然后,当一个项目被添加回 ObservableCollection 时,我希望隐藏备用面板并重新显示 TabControl。我将如何实现这一点,希望在 XAML 中使用尽可能少的代码隐藏?我知道我可以在代码隐藏中做到这一点。

以下是应用程序的关键部分。我已经隐藏了 TabControl,并包含了一个边框控件来表示当 TabControl 隐藏时我将显示的面板。

    <Window x:Class="TabTest.MainWindow"
            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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:TabTest"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <Grid>
            <Border Name="emptyTabPanel" Grid.Row="1" BorderBrush="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" 
                                BorderThickness="1,1,1,1" Margin="5,0,5,5" Visibility="Hidden">
            </Border>
            <TabControl Name="MainTabControl" Visibility="Visible">
                <TabControl.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <Label Content="{Binding Header}" MinWidth="60"/>
                            <Button BorderThickness="0" Background="Transparent" Height="16" Width="15" Margin="15,2,0,0">
                                <Image Source="images/close.png" Height="8"/>
                            </Button>
                        </StackPanel>
                    </DataTemplate>
                </TabControl.ItemTemplate>
            </TabControl>
        </Grid>
    </Window>

using System.Windows;
using System.Collections.ObjectModel;

namespace TabTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private ObservableCollection<TabEntry> tabEntries;

        public MainWindow()
        {
            InitializeComponent();

            tabEntries = new ObservableCollection<TabEntry>();
            MainTabControl.ItemsSource = tabEntries;

            for (int i = 1; i <= 5; i++)
            {
                tabEntries.Add(new TabEntry { Header = "tab " + i });
            }
        }
    }

    public class TabEntry
    {
        public string Header { get; set; }
    }
}

【问题讨论】:

    标签: c# wpf .net-core


    【解决方案1】:

    所有 ItemsControls 都提供了一个 HasItems 属性,您可以在触发器中使用该属性。与 ItemsSource.Count 上的 DataTrigger 相比,这在完全未设置 ItemsSource 时也有效。

    <TabControl ...>
        <TabControl.Style>
            <Style TargetType="TabControl">
                <Style.Triggers>
                    <Trigger Property="HasItems" Value="False">
                        <Setter Property="Visibility" Value="Collapsed" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </TabControl.Style>
        ...
    </TabControl>
    

    【讨论】:

      【解决方案2】:

      您可以使用 Style 中的 DataTriger 来实现。请注意,您需要删除 Visibility="Visible" 否则 Setter 将无法更改它。

          <TabControl Name="MainTabControl" Background="Red">
              <TabControl.Style>
                  <Style TargetType="TabControl">
                      <Style.Triggers>
                          <DataTrigger Binding="{Binding ItemsSource.Count, RelativeSource={RelativeSource Self}}" Value="0">
                              <Setter Property="Visibility" Value="Collapsed" />
                          </DataTrigger>
                      </Style.Triggers>
                  </Style>
              </TabControl.Style>
              <TabControl.ItemTemplate>
                  <!-- and so on -->
      

      【讨论】:

        【解决方案3】:

        为此,您需要一个合适的视图模型,而不是将选项卡直接绑定到集合。该视图模型将包括一个 HasItems 属性,您将绑定您的 TabControl 可见性,以及一个反向属性 - 例如 IsEmpty - 您将绑定面板的可见性。

        绑定ObservableCollectionevents 以监听项目计数的变化并为您的视图模型适当地引发PropertyChanged 事件。

        【讨论】:

        • 我知道你在说什么。我真的希望保持这个简单,而不必进入成熟的 MVVM。如果没有人想出更简单的解决方案,我会这样做。
        • 可能有一些方法可以在 XAML 中实现您想要的,老实说,我看起来并不难。但是 VM 只是一个工具,就像 XAML 一样。为什么在简单就足够的情况下复杂化很重要。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-18
        • 2021-12-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多