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

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

<TabControl ItemsSource="{Binding MyObservableCollection}" />

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

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

【问题讨论】:

    标签: wpf silverlight xaml data-binding


    【解决方案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]}" />
        

        【讨论】:

          猜你喜欢
          • 2011-09-14
          • 2014-07-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-01-12
          • 1970-01-01
          • 1970-01-01
          • 2013-03-10
          相关资源
          最近更新 更多