我想通过数据绑定动态添加和删除wpf TabControl中的选项卡。以下是示例XAML:
<Window x:Name="UI_MainWindow" x:Class="DynamicTabs.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:DynamicTabs"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid DataContext="{Binding ElementName=UI_MainWindow, Mode=OneWay}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<Button Content="Add Tab" Click="Click_AddTab"/>
</StackPanel>
<TabControl x:Name="UI_TabControl" Grid.Row="1" ItemsSource="{Binding Tabs}" SelectedItem="{Binding SelectedTab}"/>
</Grid>
</Window>
这里的代码背后是:
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
namespace DynamicTabs
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(name));
}
public List<TabItem> Tabs { get; set; }
public TabItem SelectedTab { get; set; }
public MainWindow()
{
InitializeComponent();
Tabs=new List<TabItem>();
}
private void Click_AddTab(object sender,RoutedEventArgs e)
{
TabItem newTab=new TabItem();
newTab.Header="Tab"+(Tabs.Count+1).ToString();
Tabs.Add(newTab);
OnPropertyChanged(nameof(Tabs));
SelectedTab=newTab;
OnPropertyChanged(nameof(SelectedTab));
}
}
}
行为是这样的: 首先单击“添加选项卡”:显示一个选项卡,标题为“Tab1” 任何进一步单击“添加选项卡”:TabControl的项目都会增加,同时SelectedItem似乎也会更新,但不会绘制新的标题。
我通过以编程方式设置TabControl的DataContext来尝试解决方法(请参阅https://www.codeproject.com/Articles/493538/Add-Remove-Tabs-Dynamically-in-WPF),该方法有效。 但是,我想了解,为什么我的版本不起作用。
答案 0 :(得分:1)
但是,我想了解,为什么我的版本不起作用。
因为您绑定了List<TabItem>
而不是ObservableCollection<TabItem>
。如果您只是更改它的源集合的类型:
public ObservableCollection<TabItem> Tabs { get; set; }
public TabItem SelectedTab { get; set; }
public MainWindow()
{
InitializeComponent();
Tabs = new ObservableCollection<TabItem>();
}
两种集合类型之间的区别在于后者实现了INotifyCollectionChanged接口。如果您希望在向源集合添加项目或从源集合中删除项目时视图中的ItemsControl
自动更新,则需要实现此接口。