2012-03-06 5 views
2

TabControl을 사용하여 WPF 응용 프로그램을 수행하고 있습니다. 처음에 나는 TabBase 탭의 뷰 모델에 대한 기본 클래스입니다 TabBase 항목의 ObservableCollection에 바인딩 된 TabControl에 있었다 :TabControl ItemsTemplate without ItemsSource

<TabControl 
    IsSynchronizedWithCurrentItem="True" 
    ItemsSource="{Binding Tabs}" 
    ItemTemplate="{StaticResource ClosableTabTemplate}" 
... 
public ObservableCollection<TabBase> Tabs { get; private set; } 
... 
public abstract class TabBase : ViewModelBase 
... 
public abstract class ViewModelBase : INotifyPropertyChanged 
{ 
    public virtual string DisplayName { get; protected set; } 
... 
<DataTemplate x:Key="ClosableTabTemplate"> 
    <DockPanel Width="120"> 
     <Button 
      Command="{Binding Path=CmdClose}" 
      Content="X" 
      /> 
     <ContentPresenter 
      Content="{Binding Path=DisplayName}"> 
     </ContentPresenter> 
    </DockPanel> 
</DataTemplate> 

을하지만 현재 탭이되고있는 것 같습니다 탭을 전환 할 때 나는 문제에 직면했습니다 이전에 이미 열렸더라도 매번 생성됩니다. StackOverflow를 통해 검색 here을 참조하여 here 솔루션을 찾았습니다. 선언적 ItemsSource 대신 코드에서 동적으로 탭을 생성하는 방법을 사용했습니다. 탭 전환 성능 문제는 해결되었지만 탭 헤더는 템플릿에 대한 링크가 없어 캡션 및 닫기 버튼이있는 탭 헤더 대신 작은 탭 헤더 만 보입니다. 탭 생성 코드를 조금씩 재생하면서 탭 크기와 닫기 버튼을 복원 할 수 있었지만 바인딩없이 - 캡션이없고 닫기 버튼이 작동하지 않습니다 (항목이있는 5 줄. 헤더가 원래 탭 크기로 복원 됨) :

private void AddTabItem(TabBase view) 
    { 
     TabItem item = new TabItem(); 
     item.DataContext = view; 
     item.Content = new ContentControl(); 
     (item.Content as ContentControl).Focusable = false; 
     (item.Content as ContentControl).SetBinding(ContentControl.ContentProperty, new Binding()); 

     item.Header = new ContentControl(); 
     (item.Header as ContentControl).DataContext = view; 
     (item.Header as ContentControl).Focusable = false; 
     (item.Header as ContentControl).SetBinding(ContentControl.ContentProperty, new Binding()); 
     item.HeaderTemplate = (DataTemplate)FindResource("ClosableTabTemplate"); 

     tabControl.Items.Add(item); 
    } 

질문 : ItemsTemplate이 ItemsSource 바인딩없이 TabControl에서 작동하도록하려면 어떻게해야합니까?

답변

2

명시 적으로 item.Header를 ContentControl로 설정하면 HeaderTemplate이 해당 개체를 DataContext로 사용하고 있습니다. 일반적으로 Header 속성은 ViewModel을 가져오고 ContentPresenter는 해당 (비 시각적 인) 객체를 가져 와서 HeaderTemplate을 적용합니다. 이제 ViewModel을 계층의 한 수준 아래로 밀어 템플릿이 데이터와 동일한 위치에 적용되지 않도록합니다. 이동 중 하나가 바인딩 문제를 해결하지만, 하나 또는 다른 상황에 더 잘 작동 할 수 있어야합니다

item.Header = view; 

또는

(item.Header as ContentControl).ContentTemplate = (DataTemplate)FindResource("ClosableTabTemplate"); 
+0

그것은 마술을은 "첫 번째 방법은"이 문제를 해결! 고맙습니다! – sarh