2017-05-17 7 views
0

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.

+0

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? –

+0

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 *. –

Antwort

0

Allerdings würde ich gerne verstehen, warum meine Version nicht funktioniert.

Da Sie an eine List<TabItem> anstelle einer ObservableCollection<TabItem> Bindung gebunden sind. Wenn Sie einfach nur die Art der Sammlung Quelle ändern funktioniert es:

public ObservableCollection<TabItem> Tabs { get; set; } 
public TabItem SelectedTab { get; set; } 
public MainWindow() 
{ 
    InitializeComponent(); 
    Tabs = new ObservableCollection<TabItem>(); 
} 

Der Unterschied zwischen den beiden Sammlungstypen ist, dass diese den INotifyCollectionChanged-Schnittstelle implementiert. Die Implementierung dieser Schnittstelle ist erforderlich, wenn Sie möchten, dass die ItemsControl in der Ansicht automatisch aktualisiert wird, wenn Sie ein Element zur Quellsammlung hinzufügen oder daraus entfernen.

Verwandte Themen