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

时间:2009-07-24 11:10:29

标签: wpf silverlight xaml data-binding

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

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

随着项目的添加和从集合中删除,可以按预期添加和删除选项卡。但是,只要集合为空,SelectedItem将恢复为-1(表示没有选定的选项卡)。然后,添加项目时,SelectedItem保持为-1,并且未选中新选项卡。

如果将项目添加到空集合中,如何使TabControl选择新标签?

6 个答案:

答案 0 :(得分:12)

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

答案 1 :(得分:3)

您可以做的是订阅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; 
    }
}

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

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

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

答案 2 :(得分:2)

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

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

答案 3 :(得分:0)

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

因为您正在使用ObservableCollection,所以您知道您的集合何时更改,因此我会从集合中订阅已更改的事件并检查其中的项目数。

答案 4 :(得分:0)

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

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

为我工作:)

答案 5 :(得分:0)

def matchOnList[A: TypeTag](l: List[A]) = typeOf[A] match {
    case t if t =:= typeOf[Int] =>
      l.asInstanceOf[List[Int]].foreach(c => println(2 * c))
    case _ => println("Not matched")
  }

val a = List(1)

matchOnList(a)