2017-05-17 14 views
0

데이터 바인딩을 통해서만 wpf TabControl에서 탭을 동적으로 추가 및 제거하고 싶습니다. 하나 개의 탭 헤더로 표시됩니다 "TAB1"wpf 동적 탭이 첫 번째 헤더 이상을 표시하지 않는 이유는 무엇입니까?

<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)); 
     } 
    } 
} 

동작이 같다 "탭 추가"에 첫 번째 클릭은 다음 예제 XAML입니다 "추가 탭"에 대한 추가 클릭 : TabControl의 항목이 증가하고 SelectedItem이 업데이트 된 것으로 보이지만 새 헤더는 그려지지 않습니다.

TabControl의 DataContext를 프로그래밍 방식으로 설정하여 해결 방법을 시도했습니다 (https://www.codeproject.com/Articles/493538/Add-Remove-Tabs-Dynamically-in-WPF 참조). 그러나 이해하고 싶습니다. 왜 내 버전이 작동하지 않습니다.

+0

글쎄, 당신은 확실히'SelectedTab'을'PropertyChanged'를 일으키지 않고 업데이트 할 수 없습니다. 간결함을 위해 그것을 생략 했습니까? 그리고'Tabs'는'List'가 아니라'ObservableCollection '이어야합니다. 그렇지 않으면'TabControl'에서 변경된 사항을 어떻게 알 수 있습니까? –

+0

당신은 창에'INotifyPropertyChanged'을 구현해서는 안되며'TabItem'과 같은 컨트롤 타입의 List 나 ObservableCollection을 갖는 것은 대단히 나쁜 생각입니다. 그러나'TabControl'은 그 규칙의 특별한 경우입니다. 가상화가 더럽다. –

답변

0

그러나 저는 왜 내 버전이 작동하지 않는지 이해하고 싶습니다.

ObservableCollection<TabItem> 대신 List<TabItem>에 바인딩되어 있기 때문입니다. 당신은 단순히 작동 소스 모음의 유형을 변경하는 경우 :

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

두 콜렉션 유형의 차이는 후자가 INotifyCollectionChanged 인터페이스를 구현하는 것입니다. 원본 컬렉션에서 항목을 추가하거나 제거 할 때보기의 ItemsControl을 자동으로 업데이트하려면이 인터페이스를 구현해야합니다.