Ich möchte Registerkarten dynamisch von einem WPF TabControl nur über Datenbindung hinzufügen und entfernen. Hier ist das Beispiel XAML:Warum wpf dynamische Registerkarten zeigen nicht mehr als erste Header?
<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>
Und hier der Code hinter:
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));
}
}
}
Das Verhalten ist wie folgt: Klicken Sie zuerst auf "Add Tab": ein Register wird mit Kopf "Tab1" gezeigt Weitere Klicks auf "Add Tab": Die Elemente des TabControls werden erhöht, auch das SelectedItem scheint aktualisiert zu sein, aber es werden keine neuen Header gezeichnet.
Ich versuchte eine Problemumgehung (siehe https://www.codeproject.com/Articles/493538/Add-Remove-Tabs-Dynamically-in-WPF), indem Sie den DataContext des TabControl programmgesteuert festlegen, was funktioniert. Allerdings würde ich gerne verstehen, warum meine Version nicht funktioniert.
Nun, Sie können 'SelectedTab' natürlich nicht so aktualisieren, wie Sie es tun, ohne 'PropertyChanged' zu erhöhen. Hast du das aus Gründen der Kürze einfach weggelassen? Und 'Tabs' müssen' ObservableCollection 'sein, nicht' List'. Sonst wie soll das 'TabControl' etwas geändert wissen? –
Sie sollten 'INotifyPropertyChanged' nicht in einem Fenster implementieren, und es ist normalerweise eine sehr schlechte Idee, eine List oder ObservableCollection eines Kontrolltyps wie' TabItem' zu haben, aber 'TabControl' ist eine Art Sonderfall mit dieser Regel, weil * murmeln murmeln virtualisierung *. –