我想通过数据绑定动态添加和删除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));
}
}
}
行为是这样的:首先点击“添加标签”:显示一个标签, Headers 为“Tab1”任何进一步点击“添加标签”:TabControl的项目增加,同时SelectedItem似乎更新,但没有绘制新 Headers .
我通过以编程方式设置TabControl的DataContext来尝试一种解决方法(参见https://www.codeproject.com/Articles/493538/Add-Remove-Tabs-Dynamically-in-WPF) . 但是,我想了解,为什么我的版本不起作用 .
1 回答
因为您绑定到
List<TabItem>
而不是ObservableCollection<TabItem>
. 如果您只是更改源集合的类型,它可以工作:两种集合类型之间的区别在于后者实现了INotifyCollectionChanged接口 . 如果希望在向源集合添加项目或从源集合中删除项目时视图中的
ItemsControl
自动更新,则需要实现此接口 .