如何确保我的 WPF TabControl 在至少包含一个选项卡时始终具有选定的选项卡?

Posted

技术标签:

【中文标题】如何确保我的 WPF TabControl 在至少包含一个选项卡时始终具有选定的选项卡?【英文标题】:How to make sure my WPF TabControl always has a selected tab when it contains at least one tab? 【发布时间】:2010-11-13 16:52:18 【问题描述】:

我有一个TabControl,其项目绑定到ObservableCollection

<TabControl ItemsSource="Binding MyObservableCollection" />

随着项目的添加和从集合中删除,选项卡会按预期添加和删除。但是,只要集合为空,SelectedItem 就会恢复为 -1(意味着没有选定的选项卡)。然后,当添加一个项目时,SelectedItem 保持在 -1 并且不选择新选项卡。

如何让TabControl 在将项目添加到空集合时选择新选项卡?

【问题讨论】:

【参考方案1】:

可能有更简单的方法,但您可以在 VM 中的 ObservableCollection 上挂钩集合更改事件,并将 SelectedItem 属性设置为新项目(假设您已将所选项目绑定到 VM 上的属性)。

【讨论】:

我会使用 SelectedItem 而不是索引,但这更像是个人的事情。 适用于 SelectedItem 但不适用于 SelectedIndex。尽管如此,任务还是完成了! @Graeme - 我确实说的是 SelectedItem,而不是 index.. 听起来你不同意我的观点 :-) 很高兴知道为什么 SelectedItem 有效但 SelectedIndex 无效 - 有什么想法吗?【参考方案2】:

您可以做的是订阅TabControl.ItemContainerGenerator.StatusChanged事件,如果状态为ContainersGenerated且TabControl的SelectedIndex为-1,则使TabControl的SelectedIndex为0;

// peopleCollection is an ObservableCollection<Person>
People peopleCollection = new People();
public Window1()

    InitializeComponent();
    // MyTabControl is an instance of TabControl
    MyTabControl.ItemsSource = peopleCollection;
    MyTabControl.ItemContainerGenerator.StatusChanged += new EventHandler(ItemContainerGenerator_StatusChanged);


void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)

    if((sender as ItemContainerGenerator).Status == System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated && MyTabControl.SelectedIndex == -1)
    
        MyTabControl.SelectedIndex = 0; 
    

有开箱即用的具有此功能的 3 方解决方案。 Telerik 的 RadTabControl 会在集合将其状态从空更改为“包含单个项目”时选择第一个项目。

在此处试用演示:http://demos.telerik.com/silverlight/#TabControl/AddingAndRemovingTabs

注意:这是一个 SL 演示,但它在 WPF 中的工作原理相同。

【讨论】:

【参考方案3】:

如果您正在寻找一个纯 MVVM 实现,那么将 Index 属性添加到 ViewModel 并在 CollectionChanged 上,如果里面没有项目,您可以设置 Index=0。在 XAML 中,您可以按如下方式绑定该索引

<TabControl ItemsSource="Binding MyObservableCollection" SelectedIndex="Binding Index" />

【讨论】:

这正是我最初所做的,但我认为我在 TabControl 得到它之前处理了该事件,因此它没有任何效果。我再试一次 - 也许我做错了什么! 确保您的 Index 属性设置器引发 propertyChanged 事件【参考方案4】:

最好的办法是可能覆盖“OnTabAdded”功能以检查是否添加了新功能(第一个),然后将 SelectedItemIndex 设置为 0;

由于您使用的是 ObservableCollection,因此您知道您的集合何时更改,因此我会从集合订阅更改的事件并检查其中的项目数。

【讨论】:

我已经尝试在 CollectionChanged 事件处理程序中将 SelectedIndex 设置为 0,但它没有任何效果 - 也许我的处理程序在事件到达 TabControl 之前被调用。【参考方案5】:

我遇到了同样的问题,并设法通过将所选项目绑定到动态列表中的第一项来解决它。

<TabControl ItemsSource="Binding MyObservableCollection" SelectedItem="Binding MyObservableCollection.First" />

为我工作:)

【讨论】:

【参考方案6】:
<TabControl ItemsSource="Binding MyObservableCollection" SelectedItem="Binding MyObservableCollection[0]" />

【讨论】:

以上是关于如何确保我的 WPF TabControl 在至少包含一个选项卡时始终具有选定的选项卡?的主要内容,如果未能解决你的问题,请参考以下文章

WPF TabControl 如何在鼠标向上而不是鼠标向下更改选项卡?

WPF ComboBox SelectedItem 在 TabControl 开关上设置为 Null

xaml / wpf TabControl如何使用屏幕的100%拉伸

WPF ComboBox SelectedItem在TabControl Switch上设置为Null

在 WPF Tabcontrol 标题模板中显示 SelectedIndex

如何将 TabControl 的项目绑定到 wpf 中的可观察集合?